Wenn ich eine Bash-Skriptdatei sudo ausführe, werden dann alle Befehle innerhalb des Bash-Skripts auch als sudo ausgeführt?

30

Ich möchte ein automatisiertes Nachinstallationsskript in Bash schreiben ( post-install.shwird zum Beispiel aufgerufen ). Das Skript fügt automatisch Repositorys hinzu und aktualisiert sie, installiert und aktualisiert Pakete, bearbeitet Konfigurationsdateien usw.

Wenn ich dieses Skript jetzt beispielsweise mit ausführe sudo post-install.sh, werde ich nur sudoeinmal zur Eingabe eines Kennworts aufgefordert , oder muss ich das sudoKennwort bei jedem Aufruf eines Befehls innerhalb des Skripts eingeben, für den eine sudoBerechtigung erforderlich ist ? Mit anderen Worten, übernehmen die Befehle im Bash-Skript sozusagen die Ausführungsberechtigungen?

Und wenn sie tatsächlich tun , ist es noch eine Möglichkeit , dass die sudoBerechtigungen Timeout (wenn zum Beispiel ein bestimmte Befehl lange genug dauert , die überschreiten sudoTimeout)? Oder wird der anfängliche sudoPasswort Eintritt für die gesamte Dauer des gesamten Skript dauern?

Anständiger Dabbler
quelle
4
Möglicherweise möchten Sie sich einige Tools ansehen, die speziell für diese Aufgabe entwickelt wurden. 3 gebräuchliche sind: Marionette, Koch und Ancible.
Spuder
@spuder und für größere Enterprise-Level - Architektur und die Sicherheit Ihres Konfigurationsmanagements, können Sie CFEngine 3. (Nicht für schwache Nerven, noch für einmalige Befehle.) verwenden
Wildcard

Antworten:

38

F # 1: Werde ich nur einmal zur Eingabe eines Sudo-Passworts aufgefordert oder muss ich das Sudo-Passwort bei jedem Aufruf eines Befehls innerhalb des Skripts eingeben, für den eine Sudo-Berechtigung erforderlich ist?

Ja, einmal für die Dauer der Ausführung Ihres Skripts.

HINWEIS: Wenn Sie Anmeldeinformationen für angeben, sudoist die Authentifizierung in der Shell, in der Sie das Kennwort eingegeben haben, in der Regel 5 Minuten lang gültig. Darüber hinaus werden alle untergeordneten Prozesse, die von dieser Shell ausgeführt werden, oder alle Skripts, die in der Shell ausgeführt werden (Ihr Fall), ebenfalls auf der höheren Ebene ausgeführt.

F # 2: Gibt es immer noch eine Möglichkeit, dass das Zeitlimit für die sudo-Berechtigungen überschritten wird (wenn zum Beispiel ein bestimmter Befehl lange genug dauert, um das sudo-Zeitlimit zu überschreiten)? Oder dauert die anfängliche Eingabe des Sudo-Passworts für die gesamte Dauer des gesamten Skripts?

Nein, innerhalb des Skripts tritt keine Zeitüberschreitung auf. Nur wenn Sie sie interaktiv in die Shell eingeben, in der die Anmeldeinformationen bereitgestellt wurden. Bei jeder sudoAusführung innerhalb dieser Shell wird das Timeout zurückgesetzt. In Ihrem Fall bleiben die Anmeldeinformationen jedoch so lange erhalten, wie das Skript Befehle in diesem Skript ausführt und ausführt.

Auszug aus der sudo-Manpage

Diese Grenze ist richtlinienspezifisch. Das Standard-Timeout für die Kennworteingabeaufforderung für die sudoers-Sicherheitsrichtlinie beträgt 5 Minuten.

slm
quelle
1
Die Antwort auf Q1 lautet "Nein, Sie werden nicht erneut dazu aufgefordert."
Dannysauer
@dannysauer - lies sein Q nochmal. Ich sage Ja, um nur einmal nach dem Passwort gefragt zu werden!
SLM
Die Frage lautet "Ist es a oder b?", Und nur "Ja" zu sagen, machte nicht klar, ob es "Ja, a" oder "Ja, b" war. Ich versuche nur, die Dinge für zukünftige Leser zu klären. : D
dannysauer
@dannysauer - siehe update.
slm
1
Diese neue Frage wäre: stackoverflow.com/questions/3522341/… . sudo -u $(logname) <command>sollte arbeiten.
Gauthier,
17

bashAlle untergeordneten Prozesse werden mit Superuser-Berechtigungen ausgeführt. Sie müssen also kein Kennwort für Befehle in Ihrem Bash-Skript erneut eingeben.

Das sudoTimeout gilt nur für den (späteren) separaten Aufruf von sudo. Es würde sich nicht auf Ihren bereits laufenden Bash-Prozess oder einen seiner Nachkommen auswirken.

Laurence Gonsalves
quelle
3

Diese Antworten sind wahrscheinlich alle richtig. Dies ist jedoch (soweit mir bekannt ist) nicht die allgemein übliche Methode zum Erstellen von Bash-Skripten, für die sudoBerechtigungen erforderlich sind . Im Allgemeinen wird im oberen Bereich des Skripts davon ausgegangen, dass es nicht mit sudoBerechtigungen ausgeführt wurde. Rufen sudo -vSie stattdessen sich selbst an (wodurch der Benutzer nach seinem Kennwort gefragt wird), um eine sudoSitzung einzurichten . Sie können entweder echoeinen erläuternden Text vor der Eingabeaufforderung eingeben oder die sudoeigene Eingabeaufforderung mit dem -pSchalter überschreiben , um dem Benutzer mitzuteilen, dass Sie sudofür einige Befehle Zugriff benötigen .

Dann sollten Sie in Ihrem Skript in Ordnung sein, sudodie erforderlichen Befehle (und nur die erforderlichen Befehle) ohne weitere Kennwortanfragen aufzurufen. Wenn Sie der Meinung sind, dass eine bestimmte Gruppe von Befehlen, die in Ihrem Skript zusammen ausgeführt werden (unabhängig von ihrer eigenen Verwendung sudo), über das sudo-Zeitlimit hinausgeht, können Sie sudo -vdie sudoSitzung in der Mitte aufrufen , um eine Art "Keep-Alive " auszugeben '.

Wenn die sudo'Sitzung' während des Skripts abläuft, wird der Benutzer einfach aufgefordert, sein Kennwort einzugeben, wenn Sie das nächste Mal einen sudo-Befehl im Skript ausführen.

alexrussell
quelle
1
Angenommen, einer der Schritte des Skripts besteht darin, einen neuen Linux-Kernel zu erstellen. Dies kann beispielsweise zwei Stunden dauern. Es könnte eine Herausforderung sein, die Sitzung am Leben zu halten. Wie sind Sie damit umgegangen?
Gauthier,
Das kannst du nicht. Wenn Sie das nächste Mal anrufen, werden sudo -vSie den Benutzer erneut nach dem Kennwort fragen. Meiner Meinung nach nicht das schlimmste Problem. Vielleicht ist es hilfreich, den Benutzer auf den Mechanismus aufmerksam zu machen.
Alexandrussell
Das Gegenteil davon ist, dass der Benutzer das Skript mit sudo nach den anderen Antworten aufrufen muss und dann sudo -u $SUDO_USERalle Befehle, die kein Rootbefehl erfordern, nicht mit erhöhten Rechten ausgeführt werden müssen. Es fügt leider mehr Code hinzu, ist jedoch die einzige zuverlässige Methode, um Stammdinge in einem lang laufenden Prozess auszuführen.
dragon788
Ich denke, ich sollte klarstellen, dass eine andere Möglichkeit, dies zu tun, darin besteht, sudo einmal am Anfang des Skripts aufzurufen, um eine temporäre Datei zu /etc/sudoers.dverwenden, visudo -c -f /tmp/tempsudoersum sicherzustellen, dass die Datei gültig ist, bevor sie kopiert wird, und diese Datei dann zu entfernen, wenn sie fertig ist (Verwenden einer Falle beim Beenden / Fehler, um sicherzustellen, dass die Eskalation nicht missbraucht werden kann). Die sicherste Implementierung würde es Ihrem Benutzer nur ermöglichen, die spezifischen Befehle in Ihrem Skript mit spezifischen Argumenten ohne Kennwort auszuführen, NOPASSWDindem Sie jeden Befehl / jedes Argument in einem Array speichern, um die Datei zu erstellen.
Dragon788
Es ist etwas spät, hier auf @Gauthier zurückzukommen, aber es scheint, dass ich mich geirrt habe, als ich sagte, dass Sie eine sudoSitzung nicht am Leben erhalten können, wenn eine bestimmte Aufgabe länger dauert als die Zeitüberschreitung. Diese Technik habe ich neulich in Mathias Bynens 'Dotfiles Repo entdeckt: while true; do sudo -n true; sleep 60; kill -0 "$$" || exit; done 2>/dev/null &- github.com/mathiasbynens/dotfiles/blob/master/.macos#L13
alexrussell