Meilleures pratiques sur l'utilisation de sudo dans un script bash

11

J'ai un script bash long et de longue durée où une poignée de commandes doivent être exécutées 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é du fichier et autres.

J'ai trouvé quelques méthodes, mais chacune a 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, d'après la façon dont le code est écrit. sudoest écrit avant les quelques instructions qui doivent réellement être exécutées par root, mais si le temps entre chaque sudoappel est trop long, sudoil demande à nouveau un mot de passe. De plus, 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 -cdevant presque toutes les lignes. Il est également possible de trouver le nom d'utilisateur d'origine après sudo, mais c'est compliqué.

Y a-t-il une meilleure façon?

Edit: je n'ai posté ici que de petits scripts absurdes pour montrer de quoi je parle. Dans le script actuel, j'ai quelques lignes qui ont besoin de sudo (démarrage et arrêt des services), des lignes où cela n'a pas d'importance s'il y a sudo et pas mal de lignes qui doivent vraiment être exécutées sans sudo.

Dakkaron
la source
4
C'est très rarement nécessaire. Dans la plupart des cas, vous exécutez simplement le script avec sudos'il doit avoir des autorisations élevées. Mais il est inutile de passer su username -cà l'exécution d'un echo. En d'autres termes, cela ressemble à un [XY]. Pourriez-vous modifier et expliquer ce que votre script va réellement faire et pourquoi vous pensez que vous devez changer d’utilisateur si souvent?
terdon
1
@ElderGeek avez-vous collé le mauvais lien? Cela ne semble même pas lié. Il s'agit probablement d'un doublon de Comment exécuter la commande «sudo» dans un script? mais j'espère que l'OP peut expliquer un peu plus.
terdon
@terdon Il semblerait que oui. Nettoyer.
Elder Geek
Ceci est juste un exemple de script. Je ne voulais pas coller un script de plus de 200 lignes ici. Je vais modifier la réponse pour plus de détails.
Dakkaron
Avez-vous envisagé l'option de validation, décrite dans man sudo? -v, --validate 'Mettez à jour les informations d'identification mises en cache de l'utilisateur, en authentifiant l'utilisateur si nécessaire. Pour le plugin sudoers, cela prolonge le délai d'attente sudo pendant 15 minutes supplémentaires par défaut, mais n'exécute pas de commande. Toutes les politiques de sécurité ne prennent pas en charge les informations d'identification mises en cache. ' (Si vous l'exécutez assez souvent, l'authentification sudo ne devrait pas
expirer

Réponses:

5

Concernant 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_USERest le nom d'utilisateur du sudoer. Vous pouvez également utiliser $(logname)à sa place.

Fonctionnant sur ma machine:

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

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 permettre regularà l'hôte machine1de s'exécuter command1et en command2tant que root, sans authentification par mot de passe avec:

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

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

waltinator
la source
0

Cela peut peut-être aider:

chmod 775 yourscript.sh

Ensuite, vous pouvez utiliser sudo à l'intérieur du script (sans invite de mot de passe) Et vous ne pouvez pas utiliser sudo pour d'autres commandes à l'intérieur de votre script.

1337 HaXxoR
la source
Je crains que cela ne fonctionne pas. chmod 775vous permet uniquement d'exécuter le fichier et ne modifie ni l'utilisateur qui exécute le fichier ni ses droits.
Dakkaron