web-dev-qa-db-fra.com

Comment entrer un mot de passe une seule fois dans un script bash nécessitant sudo

Les données

  • Je veux que les utilisateurs opérateurs sur cette machine montent leurs propres partages cifs
  • Le fichier sudoers contient déjà la commande /bin/mount -t cifs //*/* /media/* -o username=* pour tous les opérateurs.
  • Je souhaite que les utilisateurs montent un partage cifs via un script en tapant le mot de passe une seule fois, pas deux fois.
  • Le mot de passe Sudo et le mot de passe cifs sont identiques.

Ce que j'ai déjà

Ce script fonctionne:

#!/bin/bash
Sudo 'mount -t cifs //192.168.1.1/home /media/$USER/home -o username=$USER'

... mais les utilisateurs doivent saisir le même mot de passe deux fois!

  • Une fois pour Sudo
  • Une fois pour le mont lui-même

Cela fonctionnerait aussi:

#!/bin/bash
echo -n Password: 
read -s szPassword
echo $szPassword | Sudo -S sh -c 'echo $szPassword | mount -t cifs //192.168.1.1/home /media/$USER/home -o username=$USER'

... mais cela nécessiterait que je permette à tous les utilisateurs d'opérateurs de pouvoir Sudo sh (problème de sécurité majeur)

Question

Comment monter un partage cifs en bash ¹ sans mettre sh dans le fichier sudoersni créer un fichier permanent/temporaire ???

Note 1: pas de python, Perl, C, Go, ... s'il vous plaît?
Note 2: Je sais que je peux simplement supprimer le mot de passe via le fichier sudoers, mais j'essaie de renforcer la sécurité, pas de la desserrer, sans renoncer à la commodité. ..

21
Fabby

Je suis stupide!

Le script suivant:

#!/bin/bash
read -p "Password: " -s szPassword
printf "%s\n" "$szPassword" | Sudo --stdin mount -t cifs //192.168.1.1/home /media/$USER/home -o username=$USER,password="$szPassword"

fonctionne et:

  1. Ne crée pas de fichiers contenant des mots de passe
  2. Permet à l'utilisateur de saisir un seul mot de passe pour plusieurs partages (y compris ceux Windows)
  3. N'a pas besoin de privilèges supplémentaires à accorder. : -)
7
Fabby

Au lieu de cela, vous devriez demander à l'utilisateur d'utiliser Sudo sous le nom Sudo script. il suffit de vérifier si le script est exécuté en tant que root, sinon demandez-le

if [[ $EUID -ne 0 ]]; then
   echo "This script must be run as root, use Sudo "$0" instead" 1>&2
   exit 1
fi

N'essayez pas de capturer le mot de passe de vos utilisateurs.

24
Braiam

N'exigez pas de Sudomot_de_passe pour exécuter cette commande; l'invite de mot de passe reste pour mountname__.

Dans sudoersname__, incluez quelque chose comme:

ALL        ALL = NOPASSWD: /bin/mount -t cifs //*/* /media/* -o username=*

Après avoir inclus cela, Sudone demandera plus de mot de passe pour cette commande spécifique; l'utilisateur doit toujours fournir un mot de passe à la commande mountname__.

Note: J'ai pris la commande mot à mot de ce que vous avez inclus dans la question; Je n'ai pas vérifié si ses caractères génériques permettraient aux utilisateurs de faire quelque chose de méchant. Lisez la page de manuel sudoerspour des exemples de méchanceté. Notez en particulier que cette ligne dans sudoerspermet à l'utilisateur d'ajouter un nombre quelconque de commutateurs -o ou d'autres arguments à mountname __. Vous pouvez repenser votre approche, par exemple. en ajoutant un script tel que @Braiam propose et permet de l'exécuter via Sudosans authentification supplémentaire. Le script garantit ensuite que les utilisateurs ne peuvent exécuter que la forme spécifique mountque vous souhaitez qu'ils exécutent.

De plus, au lieu de permettre cela à tous les utilisateurs, vous pouvez également le limiter aux membres d’un certain groupe, par exemple. vous pouvez créer un groupe cifsmountet avoir ensuite

%cifsmount ALL = NOPASSWD: /bin/mount -t cifs //*/* /media/* -o username=*
3
Oliphaunt

Une solution générale à ces problèmes consiste à placer le préambule suivant en tête de votre Sudo nécessitant des scripts:

#!/bin/bash
case $EUID in
   0) : cool we are already root - fall through ;;
   *) # not root, become root for the rest of this session
      # (and ask for the Sudo password only once)
      Sudo $0 "$@" ;;
esac
# now the present process is effective-UID  (root)
# so there's no need to put Sudo in front of commands

any more commands here will run as superuser ...

Évidemment, cela présente un inconvénient, car si certaines commandes du script ne nécessitent pas l'exécution de Sudo, il existe une élévation inutile des privilèges ici.

Quoi qu'il en soit, j'ai pensé partager ce petit conseil. La chose la plus gentille à ce sujet est que si vous êtes déjà efficace (par exemple, si vous l’avez déjà appelé sous Sudo), il fait normalement la bonne chose. Donner une erreur et vous obliger à retaper/réexécuter (avec Sudo) est également moins convivial.

Vous pouvez également consulter la variable timestamp_timeout dans man 5 sudoers qui indique à Sudo de ne pas mémoriser les informations d'identification de l'utilisateur pendant un nombre limité de minutes (et peut être fractionnaire).

1
arielf