web-dev-qa-db-fra.com

Les meilleures pratiques pour utiliser Sudo dans un script bash

J'ai un long et long script bash dans lequel une poignée de commandes doit être exécutée en tant que root, tandis que la majorité des commandes doivent être exécutées en tant qu'utilisateur normal avant Sudo, car cela gâcherait la propriété des fichiers, etc.

Je suis venu avec des méthodes, mais chacun d'entre eux ont des problèmes

Méthode 1: Utiliser Sudo dans le fichier

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

Cela semblerait bien, vu la façon dont le code est écrit. Sudo est écrit avant les quelques instructions devant être exécutées par root, mais si le délai entre chaque appel Sudo est trop long, Sudo demande à nouveau un mot de passe. De même, si la première exécution de Sudo échoue, par exemple. En raison d'un mot de passe invalide, le reste du script est toujours exécuté.

Méthode 2: utiliser Sudo pour appeler le fichier puis revenir à l'utilisateur d'origine si nécessaire

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

Cela craint aussi, car je dois ajouter su username -c devant presque chaque ligne. Il est également possible de trouver le nom d'utilisateur d'origine après Sudo, mais c'est fastidieux.

Y a-t-il un meilleur moyen?

Edit: je n’ai posté ici que de petits scripts insensés pour montrer de quoi je parle. Dans le script actuel, certaines lignes ont besoin de Sudo (services de démarrage et d’arrêt), d’autres où il n’importe pas de Sudo et beaucoup de lignes devant être exécutées sans Sudo.

8
Dakkaron

En ce qui concerne la méthode 2, il est plus facile d’utiliser une fonction. Par exemple:

#!/bin/bash

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

export -f func

func
su "$Sudo_USER" -c 'func'

$Sudo_USER est le nom d'utilisateur de sudoer. Vous pouvez également utiliser $(logname) à la place.

Courir sur ma machine:

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

En lisant man sudoers, on voit:

 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. 

Ainsi, vous pouvez autoriser regular sur l'hôte machine1 à exécuter command1 et command2 en tant qu'utilisateur root, sans authentification par mot de passe avec:

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

mais lisez chacun de man -k Sudo pour plus de détails.

2
waltinator