Modo corretto per consentire all'utente di immettere la password per uno script bash utilizzando solo la GUI (con il terminale nascosto)


8

Ho creato uno script bash che usa kdialog esclusivamente per interagire con l'utente. Viene avviato da un file ".desktop" in modo che l'utente non veda mai il terminale. Sembra al 100% come un'app GUI (anche se è solo uno script bash). Funziona solo in KDE (Kubuntu 12.04).

Il mio unico problema è gestire l'immissione della password in modo sicuro e conveniente. Non riesco a trovare una soluzione soddisfacente.

Lo script è stato progettato per essere eseguito come un normale utente e per richiedere la password quando è necessario un comando sudo. In questo modo, la maggior parte dei comandi, quelli che non richiedono diritti sudo, vengono eseguiti come l'utente normale. Ciò che accade (quando lo script viene eseguito dal terminale) è che all'utente viene richiesta una volta la password e il timeout sudo predefinito consente di terminare lo script, inclusi eventuali comandi sudo aggiuntivi, senza richiedere nuovamente all'utente. Questo è come voglio che funzioni anche quando eseguito dietro la GUI.

Il problema principale è che l'utilizzo kdesudoper avviare il mio script, che è il modo standard della GUI, significa che l'intero script viene eseguito dall'utente root. Quindi le proprietà dei file vengono assegnate all'utente root, non posso fare affidamento sui ~/percorsi e molte altre cose sono tutt'altro che ideali. L'esecuzione dell'intero script come utente root è solo una soluzione molto insoddisfacente e penso che sia una cattiva pratica.

Apprezzo qualsiasi idea per consentire a un utente di inserire la password sudo una sola volta tramite la GUI senza eseguire l'intero script come root. Grazie.

Risposte:


14

L' -Aopzione sudo consente di specificare un programma di supporto (nella variabile SUDO_ASKPASS) che chiederà la password.

Crea uno script per chiedere la password (myaskpass.sh):

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

Quindi inserire questa riga all'inizio dello script:

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

e sostituisci tutte le occorrenze di sudo <command>con:

sudo -A <command>

È possibile utilizzare qualsiasi password che richiede il programma desiderato invece di zenity. Ho dovuto incapsularlo in uno script perché SUDO_ASKPASS deve puntare a un file, quindi non funzionerà con l' --passwordopzione richiesta da zenity.

Quanto sopra funziona come un incantesimo se viene eseguito dalla riga di comando o se si sceglie Esegui nel terminale dopo aver fatto doppio clic sul file di script nel file manager, ma se si sceglie Esegui o si tenta di avviarlo da un file .desktop tutti sudochiederanno il di nuovo per la password.


Se non si desidera affatto una finestra del terminale, è possibile memorizzare la password in una variabile e reindirizzarla sudo -S. Forse ci sono alcuni problemi di sicurezza, ma penso che sia abbastanza sicuro (leggi i commenti su questa risposta ).

Inserisci questa riga all'inizio del tuo script:

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

e sostituisci tutte le occorrenze di sudo <command>con:

echo -e $PASSWD | sudo -S <command>

Grazie. È molto interessante. Tuttavia, quando si utilizza questo si perde il solito timeout sudo (ad esempio, 15 minuti). Il mio script, che ha oltre 50 comandi sudo, ora richiede la password dell'utente 50+ volte! Ho cercato su Google un po 'e non ho visto una soluzione. Ne conosci uno?
MountainX,

Grazie per l'aggiornamento. L'alternativa che suggerisci è qualcosa che avevo escluso a causa di problemi di sicurezza, ma dalla lettura dei commenti sul link che hai fornito, penso che probabilmente sia abbastanza sicuro. Ed è un modo semplice per risolvere il problema. Grazie.
MountainX

Il test sul mio sistema deve essere sudo -s(minuscolo s) e non sudo -S(maiuscolo s).
WinEunuuchs2Unix

0

Questo si basa sulla risposta eccellente di Eric Carvalho. Lo sto postando per approfondire il problema che ho riscontrato. In particolare, quando si utilizza questo viene perso il solito timeout sudo (ad esempio, 15 minuti). Il mio script, che ha oltre 50 comandi sudo, ora richiede la password dell'utente 50+ volte!

Ecco un esempio di lavoro completo di tutte le parti della soluzione. Consiste in uno script bash, uno script "myaskpass" come suggerito da Eric e un file ".desktop". Il tutto dovrebbe essere al 100% GUI (nessuna interazione terminale), quindi il file .desktop è essenziale (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=

E uno script di prova stesso. Questo ti chiederà due volte la password quando usi questa soluzione. (Normalmente, lo chiederebbe solo una volta a causa del timeout predefinito sudo.)

#!/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

Eseguendo questo script dalla riga di comando, la password viene richiesta una sola volta. In esecuzione dalla GUI (facendo clic su .desktop o .sh nel file manager) ogni volta che si sudo -Ariassume la password. Proverò a capirlo.
Eric Carvalho,

Ho appena aggiornato la mia risposta.
Eric Carvalho,

Eric ... hai trovato una soluzione al problema?
Anthony

0

Il seguente script funziona tramite riga di comando, file desktop o doppio clic, richiede la password una sola volta e il modello di comando sudo -Sp '' <your command here> <<<${sudo_password}può essere utilizzato più volte in qualsiasi punto del file:

    # 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}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.