Best practice sull'uso di sudo in uno script bash


11

Ho uno script bash lungo e di lunga durata in cui una manciata di comandi deve essere eseguita come root mentre la maggior parte dei comandi deve essere eseguita come utente normale prima di sudo, perché rovinerebbe la proprietà dei file e simili.

Ho escogitato alcuni metodi, ma ognuno di essi ha dei problemi

Metodo 1: utilizzo di sudo all'interno del file

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

Questo sembrerebbe buono, dal modo in cui è scritto il codice. sudoviene scritto prima delle poche istruzioni che devono essere effettivamente eseguite dal root, ma se l'intervallo tra ogni sudochiamata è troppo lungo sudorichiede nuovamente una password. Inoltre, se la prima esecuzione di sudonon riesce, ad esempio a causa di una password non valida, il resto dello script viene comunque eseguito.

Metodo 2: usare sudo per chiamare il file e poi tornare all'utente originale quando necessario

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

Anche questo fa schifo, perché devo aggiungere su username -cdavanti a quasi ogni riga. Anche trovare il nome utente originale dopo sudoè possibile, ma ingombrante.

Esiste un modo migliore?

Modifica: ho pubblicato qui solo piccoli script senza senso per mostrare di cosa sto parlando. Nello script attuale ho alcune linee che richiedono sudo (avvio e arresto dei servizi), alcune linee in cui non importa se c'è sudo e molte linee che devono essere effettivamente eseguite senza sudo.


4
Questo è molto raro. Nella maggior parte dei casi, basta eseguire lo script con sudose deve disporre di autorizzazioni elevate. Ma non ha senso passare su username -ca eseguire un echo. In altre parole, questo sembra un [XY]. Potresti modificare e spiegare cosa farà effettivamente il tuo script e perché ritieni di dover cambiare utente così spesso?
terdon,

1
@ElderGeek hai incollato il link sbagliato? Questo non sembra nemmeno correlato. Questo probabilmente è un duplicato di Come posso eseguire il comando 'sudo' all'interno di uno script? ma spero che l'OP possa spiegare un po 'di più.
terdon,

@terdon Sembra così. Pulire.
Anziano Geek,

Questo è solo uno script di esempio. Non volevo incollare uno script di oltre 200 righe qui. Modificherò la risposta per maggiori dettagli.
Dakkaron,

Hai considerato l'opzione di convalida, descritta in man sudo? -v, --validate 'Aggiorna le credenziali memorizzate nella cache dell'utente, autenticando l'utente se necessario. Per il plug-in sudoers, questo estende il timeout sudo per altri 15 minuti per impostazione predefinita, ma non esegue un comando. Non tutte le politiche di sicurezza supportano le credenziali memorizzate nella cache. " (Se lo esegui abbastanza spesso, l'autenticazione sudo non dovrebbe
scadere

Risposte:


5

Per quanto riguarda il metodo 2, è più facile usare una funzione. Per esempio:

#!/bin/bash

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

export -f func

func
su "$SUDO_USER" -c 'func'

$SUDO_USERè il nome utente del sudoer. Puoi anche usare $(logname)al suo posto.

In esecuzione sulla mia macchina:

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

2

Leggendo man sudoers, si vede:

 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. 

Pertanto, è possibile consentire regularall'host machine1di eseguire command1e command2come root, senza autenticazione password con:

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

ma leggi ciascuno dei man -k sudodettagli.


0

Forse questo può aiutare:

chmod 775 yourscript.sh

Quindi è possibile utilizzare sudo all'interno dello script (senza richiesta di password) e non è possibile utilizzare sudo per altri comandi all'interno dello script.


Temo che non funzioni. chmod 775consente solo di eseguire il file e non cambia l'utente che sta eseguendo il file o i loro diritti.
Dakkaron,
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.