Best Practices für die Verwendung von sudo in einem Bash-Skript

10

Ich habe ein langes und lang laufendes Bash-Skript, in dem eine Handvoll Befehle als Root ausgeführt werden müssen, während die meisten Befehle als normaler Benutzer vor sudo ausgeführt werden müssen, da dies den Dateibesitz und dergleichen durcheinander bringen würde.

Ich habe mir einige Methoden ausgedacht, aber jede hat einige Probleme

Methode 1: Verwenden von sudo in der Datei

#!/bin/bash
sudo echo "I must be run by root"
touch needsToBeOwnedByUser1
echo "needs to be run by user"
sleep 1000
sudo echo "I, again, must be run by root"

Das würde gut aussehen, wenn man bedenkt, wie der Code geschrieben ist. sudowird vor den wenigen Anweisungen geschrieben, die tatsächlich von root ausgeführt werden müssen, aber wenn die Zeit zwischen jedem sudoAufruf zu lang ist, werden Sie sudoerneut nach einem Kennwort gefragt. Wenn die erste Ausführung von sudofehlschlägt, z. B. aufgrund eines ungültigen Kennworts, wird der Rest des Skripts weiterhin ausgeführt.

Methode 2: Verwenden von sudo, um die Datei aufzurufen und bei Bedarf zum ursprünglichen Benutzer zurückzukehren

#!/bin/bash
echo "I must be run by root"
su username -c 'touch needsToBeOwnedByUser1'
su username -c 'echo "needs to be run by user"'
su username -c 'sleep 1000'
echo "I, again, must be run by root"

Das ist auch scheiße, weil ich su username -cvor fast jeder Zeile hinzufügen muss. Auch das Auffinden des ursprünglichen Benutzernamens nach sudoist möglich, aber umständlich.

Gibt es einen besseren Weg?

Bearbeiten: Ich habe hier nur kleine, unsinnige Skripte gepostet, um zu zeigen, wovon ich spreche. Im eigentlichen Skript habe ich einige Zeilen, die sudo benötigen (Dienste starten und stoppen), einige Zeilen, in denen es keine Rolle spielt, ob es sudo gibt, und ziemlich viele Zeilen, die wirklich ohne sudo ausgeführt werden müssen.

Dakkaron
quelle
4
Dies wird sehr selten benötigt. In den meisten Fällen führen Sie das Skript nur aus, sudowenn es über erhöhte Berechtigungen verfügt. Aber es macht keinen Sinn, zu wechseln, su username -cum eine auszuführen echo. Mit anderen Worten, das klingt nach einem [XY]. Könnten Sie bearbeiten und erklären, was Ihr Skript tatsächlich tut und warum Sie das Gefühl haben, dass Sie so oft den Benutzer wechseln müssen?
Terdon
1
@ElderGeek hast du den falschen Link eingefügt? Das scheint nicht einmal verwandt zu sein. Dies ist wahrscheinlich ein Duplikat von Wie führe ich den Befehl 'sudo' in einem Skript aus? aber ich hoffe das OP kann ein bisschen mehr erklären.
Terdon
@terdon Es scheint so. Aufräumen.
Elder Geek
Dies ist nur ein Beispielskript. Ich wollte hier kein Skript mit mehr als 200 Zeilen einfügen. Ich werde die Antwort für weitere Details bearbeiten.
Dakkaron
Haben Sie die Validierungsoption in Betracht gezogen, die in beschrieben wird man sudo? -v, --validate 'Aktualisieren Sie die zwischengespeicherten Anmeldeinformationen des Benutzers und authentifizieren Sie den Benutzer bei Bedarf. Für das sudoers-Plugin verlängert dies das sudo-Timeout standardmäßig um weitere 15 Minuten, führt jedoch keinen Befehl aus. Nicht alle Sicherheitsrichtlinien unterstützen zwischengespeicherte Anmeldeinformationen. ' (Wenn Sie es oft genug ausführen, sollte die Sudo-Authentifizierung keine Zeitüberschreitung aufweisen.)
Sudodus

Antworten:

5

In Bezug auf Methode 2 ist es einfacher, eine Funktion zu verwenden. Zum Beispiel:

#!/bin/bash

func(){
    echo "Username: $USER"
    echo "    EUID: $EUID"
}

export -f func

func
su "$SUDO_USER" -c 'func'

$SUDO_USERist der Benutzername des Sudoer. Sie könnten auch $(logname)an seiner Stelle verwenden.

Laufen auf meinem Computer:

$ sudo bash test.sh
[sudo] password for wja: 
Username: root
    EUID: 0
Username: wja
    EUID: 1000
wjandrea
quelle
2

Beim Lesen man sudoerssieht man:

 PASSWD and NOPASSWD

   By default, sudo requires that a user authenticate him or herself
   before running a command.  This behavior can be modified via the
   NOPASSWD tag.  Like a Runas_Spec, the NOPASSWD tag sets a default for
   the commands that follow it in the Cmnd_Spec_List.  Conversely, the
   PASSWD tag can be used to reverse things.  For example:

   ray     rushmore = NOPASSWD: /bin/kill, /bin/ls, /usr/bin/lprm

   would allow the user ray to run /bin/kill, /bin/ls, and /usr/bin/lprm
   as root on the machine rushmore without authenticating himself. 

Auf diese Weise können Sie zulassen, dass der regularHost machine1ausgeführt wird command1und command2als Root ohne Kennwortauthentifizierung mit:

reguser machine1 root = NOPASSWD: /usr/local/command1, /usr/local/command2  

aber lesen Sie jedes man -k sudofür Details.

Walzer
quelle