Richtige Möglichkeit, dem Benutzer die Eingabe eines Kennworts für ein Bash-Skript nur über die GUI zu ermöglichen (wobei das Terminal ausgeblendet ist)

8

Ich habe ein Bash-Skript erstellt, das kdialog ausschließlich für die Interaktion mit dem Benutzer verwendet. Es wird aus einer ".desktop" -Datei gestartet, sodass der Benutzer das Terminal nie sieht. Es sieht zu 100% aus wie eine GUI-App (obwohl es sich nur um ein Bash-Skript handelt). Es läuft nur in KDE (Kubuntu 12.04).

Mein einziges Problem ist die sichere und bequeme Eingabe von Passwörtern . Ich kann keine zufriedenstellende Lösung finden.

Das Skript wurde entwickelt , um als normaler Benutzer ausgeführt zu werden und um das Kennwort einzugeben, wenn ein sudo-Befehl zum ersten Mal benötigt wird. Auf diese Weise werden die meisten Befehle, für die keine Sudo-Rechte erforderlich sind, als normaler Benutzer ausgeführt. Was passiert (wenn das Skript vom Terminal ausgeführt wird), ist, dass der Benutzer einmal zur Eingabe seines Kennworts aufgefordert wird und das Standard-Sudo-Timeout das Beenden des Skripts einschließlich aller zusätzlichen Sudo-Befehle ermöglicht, ohne den Benutzer erneut dazu aufzufordern. So soll es auch funktionieren, wenn es hinter der GUI ausgeführt wird.

Das Hauptproblem besteht darin, dass kdesudodas Starten meines Skripts, das die Standard-GUI-Methode ist, bedeutet, dass das gesamte Skript vom Root-Benutzer ausgeführt wird. Daher werden dem Root-Benutzer Dateieigentümer zugewiesen, auf die ich mich ~/in Pfaden nicht verlassen kann , und viele andere Dinge sind nicht ideal. Das Ausführen des gesamten Skripts als Root-Benutzer ist nur eine sehr unbefriedigende Lösung, und ich denke, es ist eine schlechte Praxis.

Ich freue mich über Ideen, wie ein Benutzer das sudo-Passwort nur einmal über die GUI eingeben kann, ohne das gesamte Skript als root auszuführen. Vielen Dank.

MountainX
quelle

Antworten:

13

Mit der -AOption sudo können Sie ein Hilfsprogramm (in der Variablen SUDO_ASKPASS) angeben, das nach dem Kennwort fragt.

Erstellen Sie ein Skript, um nach dem Passwort zu fragen (myaskpass.sh):

#!/bin/bash
zenity --password --title=Authentication

Fügen Sie dann diese Zeile am Anfang Ihres Skripts ein:

export SUDO_ASKPASS="/path/to/myaskpass.sh"

und ersetzen Sie alle Vorkommen von sudo <command>durch:

sudo -A <command>

Sie können stattdessen ein beliebiges Programm zur Kennwortabfrage verwenden zenity. Ich musste es in ein Skript einkapseln, da SUDO_ASKPASS auf eine Datei verweisen muss, damit es mit der von --passworderforderlichen Option nicht funktioniert zenity.

Das Obige funktioniert wie ein Zauber, wenn es über die Befehlszeile ausgeführt wird oder wenn Sie nach dem Doppelklick auf die Skriptdatei im Dateimanager die Option "Im Terminal ausführen" auswählen. Wenn Sie jedoch " Ausführen" auswählen oder versuchen, es über eine .desktop-Datei zu starten, werden alle sudonach dem gefragt für Passwort nochmal.


Wenn Sie überhaupt kein Terminalfenster möchten, können Sie das Kennwort in einer Variablen speichern und an weiterleiten sudo -S. Vielleicht gibt es einige Sicherheitsbedenken, aber ich denke, es ist ziemlich sicher (lesen Sie die Kommentare zu dieser Antwort ).

Fügen Sie diese Zeile am Anfang Ihres Skripts ein:

PASSWD="$(zenity --password --title=Authentication)\n"

und ersetzen Sie alle Vorkommen von sudo <command>durch:

echo -e $PASSWD | sudo -S <command>
Eric Carvalho
quelle
Vielen Dank. Das ist sehr interessant. Wenn Sie dies verwenden, geht jedoch das übliche Sudo-Timeout (z. B. 15 Minuten) verloren. Mein Skript mit über 50 sudo-Befehlen fordert jetzt mehr als 50 Mal zur Eingabe des Benutzerpassworts auf! Ich habe ein bisschen gegoogelt und keine Lösung gefunden. Kennst du einen
MountainX
Danke für das Update. Die Alternative, die Sie vorschlagen, habe ich aus Sicherheitsgründen ausgeschlossen, aber nach dem Lesen der Kommentare unter dem von Ihnen angegebenen Link denke ich, dass sie wahrscheinlich sicher genug ist. Und es ist eine einfache Möglichkeit, das Problem zu lösen. Vielen Dank.
MountainX
Beim Testen auf meinem System muss es sudo -s(Kleinbuchstaben s) und nicht sudo -S(Großbuchstaben s) sein.
WinEunuuchs2Unix
0

Dies basiert auf Eric Carvalhos ausgezeichneter Antwort. Ich poste es, um auf das Problem einzugehen, auf das ich gestoßen bin. Insbesondere bei dieser Verwendung geht das übliche Sudo-Timeout (z. B. 15 Minuten) verloren. Mein Skript mit über 50 sudo-Befehlen fordert jetzt mehr als 50 Mal zur Eingabe des Benutzerpassworts auf!

Hier finden Sie ein vollständiges Beispiel für alle Teile der Lösung. Es besteht aus einem Bash-Skript, einem "myaskpass" -Skript, wie Eric vorgeschlagen hat, und einer ".desktop" -Datei. Das Ganze sollte 100% GUI sein (überhaupt keine Terminal-Interaktion), daher ist die .desktop-Datei unerlässlich (afaik).

$ cat myaskpass.sh 
#!/bin/bash
kdialog --password "Please enter your password: "
exit 0


$ cat askpasstest1.desktop 
#!/usr/bin/env xdg-open
[Desktop Entry]
Comment=SUDO_ASKPASS tester1
Exec=bash /home/user/test/askpasstest1.sh
GenericName=SUDO_ASKPASS tester1
Name=SUDO_ASKPASS tester1
NoDisplay=false
Path[$e]=
StartupNotify=true
Terminal=false
TerminalOptions=
Type=Application
Categories=Application;Utility;
X-KDE-SubstituteUID=false
X-KDE-Username=

Und ein Testskript selbst. Dieser wird bei Verwendung dieser Lösung zweimal nach Ihrem Passwort fragen. (Normalerweise wird aufgrund des Standard-Sudo-Timeouts nur einmal gefragt.)

#!/bin/bash

sudo -k
SUDO_ASKPASS="/home/user/test/myaskpass.sh" sudo -A touch filemadeas_askpass1
touch filemadeas_regularuser1
SUDO_ASKPASS="/home/user/test/myaskpass.sh" sudo -A touch filemadeas_askpass2
touch filemadeas_regularuser2
ls -la filemadeas* > /home/user/test/fma.log
kdialog --title "Files Created" --textbox /home/user/test/fma.log 640 480
sudo rm filemadeas_*
rm fma.log

exit 0
MountainX
quelle
Wenn Sie dieses Skript über die Befehlszeile ausführen, wird das Kennwort nur einmal abgefragt. sudo -AWenn Sie über die GUI (Klicken auf .desktop oder .sh im Dateimanager) ausgeführt werden, wird das Kennwort erneut überprüft. Ich werde versuchen, das herauszufinden.
Eric Carvalho
Ich habe gerade meine Antwort aktualisiert.
Eric Carvalho
Eric ... hast du eine Lösung für das Problem gefunden?
Anthony
0

Das folgende Skript funktioniert über Befehlszeile, Desktop-Datei oder Doppelklick, fragt nur einmal nach dem Kennwort und das Befehlsmuster sudo -Sp '' <your command here> <<<${sudo_password}kann überall in der Datei mehrmals verwendet werden:

    # get sudo password
    sudo_password=$( gksudo --print-pass --message="Provide permission to make system changes: Type your password or press Cancel." -- : 2>/dev/null )
    # check for null entry or cancellation
    if [[ ${?} != 0 || -z ${sudo_password} ]]
    then
        exit 4
    fi
    if ! sudo -kSp '' [ 1 ] <<<${sudo_password} 2>/dev/null
    then
        exit 4
    fi
    # command
    sudo -Sp '' gedit "/etc/hosts" <<<${sudo_password}
Sadi
quelle