Exécuter uniquement des parties d'un script en tant que sudo, en entrant le mot de passe une seule fois


14

J'écris un script (en fait une combinaison de scripts et de makefile) qui installe des dépendances externes: certaines apt-getcommandes, certains gitclonages, construction, installation, ajout d'utilisateurs aux groupes, ...

Certaines opérations de ces scripts nécessitent des autorisations de superutilisateur, d'autres non.

Jusqu'à présent, j'ai exécuté l'ensemble du processus de création avec sudo, mais il présente certains inconvénients:

  • gitrepos que je clone obtient en roottant que propriétaire, ce qui signifie que je ne peux pas les modifier par la suite sans sudoouchown
  • les scripts qui ajoutent des utilisateurs à des groupes ne savent pas quel utilisateur ajouter depuis les whoamiretoursroot

Quelle est la meilleure façon d'exécuter en tant que superutilisateur uniquement les commandes qui en ont besoin? Idéalement, le processus nécessiterait toujours que j'entre mon sudomot de passe, mais une seule fois au tout début du processus d'installation. Il l'oublierait alors à la toute fin, mais gardez-le tout le temps jusque-là (cela peut prendre plusieurs heures).

Les solutions que j'ai trouvées en ligne comprennent:

  • sudo -vau début du script, mais si je comprends bien, cela arrive à expiration. Mon script pourrait fonctionner pendant quelques heures
  • exécuter le script avec sudo, mais les commandes qui n'ont pas besoin de superutilisateur avec sudo -u $(logname) <command>. C'est ce que je fais maintenant, mais j'ai l'impression que ce devrait être l'inverse.

Idéalement, j'aimerais que mon script:

  1. demander des informations d'identification de superutilisateur
  2. exécuter des commandes normales en tant qu'utilisateur connecté
  3. exécuter les commandes sudo avec les informations d'identification entrées à l'étape 1
  4. sudo -k pour fermer la session superutilisateur

2
Vous pouvez toujours tout exécuter en tant que sudo, et votre script peut vérifier la SUDO_USERvariable d'environnement. S'il est présent, il contiendra le nom d'utilisateur de l'utilisateur appelant sudo. Vous pouvez donc (en tant que root) afficher $ SUDO_USER: $ SUDO_GID $ vos_fichiers. De même, vous pouvez vérifier ces variables afin que vos commandes adduser sachent quel utilisateur ajouter.
roadmr

... ou exécutez tout en tant que root et utilisez su $SUDO_USER -c commandles commandes exécutées en tant qu'utilisateur normal.
Rmano

Réponses:


7

Puisque vous avez accès à sudo, créez un fichier sudoers pour vous-même, puis supprimez-le lorsque le script est terminé:

# grant this user access to the sudo commands without passwords
# add all required cmds to the CMDS alias
sudo tee /etc/sudoers.d/$USER <<END
$USER $(hostname) = NOPASSWD: /usr/bin/apt-get, /usr/sbin/adduser, /bin/rm, ...
END

# your script goes here
sudo apt-get install ...
git clone ...
sudo adduser group2 $USER
sudo adduser group1 $USER
: ...

# then, remove the sudo access
sudo /bin/rm /etc/sudoers.d/$USER
sudo -k

2

Une façon, que je ne recommanderais généralement pas, est de lire le mot de passe vous-même et d'utiliser sudol' -Soption de pour transmettre le mot de passe en cas de besoin:

#! /bin/bash
IFS= read -rsp 'Enter your password: ' password
git clone ...
sudo -S apt-get install foo -y <<<"$password"

De man sudo:

 -S, --stdin
             Write the prompt to the standard error and read the password
             from the standard input instead of using the terminal device.
             The password must be followed by a newline character.

1
Est-ce sûr? echo "$password"??
αғsнιη

@KasiyA echo "$password"ne le serait pas, mais les heredocs et les herestrings sont légèrement plus sûrs. Ils ne sont pas visibles sur la ligne de commande affichée par les outils habituels.
muru

1
Je pense, à proprement parler, echo "$password"sur le côté gauche d'un tuyau est sûr dans un script bash. echoest un shell intégré; /bin/echone fonctionne pas quand il est appelé aussi simplement echo .... Certains autres shells ont un echointégré ( dash, par exemple), mais les shells de style Bourne ne sont pas tenus d'en avoir un. Je pense donc que echo "$password" |c'est acceptable dans bash mais qu'il vaut mieux l'éviter si quelqu'un transfère le script vers un autre shell sans remarquer le problème. J'utilise un non portable [[au lieu de [dans ce script pour éviter le même genre de problème. @KasiyA
Eliah Kagan
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.