Comment toujours appliquer le mot de passe sudo pour une commande spécifique?

12

L'autre jour, je faisais des tâches de maintenance sur mon serveur Web. J'étais pressé et somnolent, alors j'ai tout fait en utilisant la sudocommande.

Et puis, j'ai accidentellement appuyé sur Ctrl+ V, en envoyant cette commande à mon serveur Web:

sudo rm -rf /*

Pour ceux qui se demandent ce que fait la commande ci-dessus: cela a supprimé tout mon serveur Web

Heureusement, j'ai eu des sauvegardes et malheureusement, j'ai dû passer deux heures de plus à rester éveillé pour corriger cette erreur géniale. Mais depuis, je me demande:

Existe-t-il un moyen de toujours appliquer le mot de passe sudo pour une commande spécifique?

Si le serveur me demandait un mot de passe, je me sauverais de beaucoup de problèmes. Ce n'est pas le cas, car j'ai exécuté environ 5 sudocommandes avant cette erreur majestueuse.

Alors, y a-t-il un moyen de le faire? J'ai juste besoin que le mot de passe avec la rmcommande soit toujours appliqué. Les autres commandes que j'utilise sont généralement nanoou les cpdeux sont (dans une certaine mesure) réversibles.

Pavel Janicek
la source
2
@solsTiCe /*est développé avant d'être transmis à la commande rm. La commande ne voit donc pas un seul argument, mais une liste d'arguments ( /bin /boot /cdrom /dev /etc /home...)
Dan
3
Une leçon importante à retenir de ceci est que vous ne devriez pas exécuter les choses avec sudo à moins que vous en ayez vraiment besoin. Je sais que cela ne répond pas à ce que vous avez demandé ici, mais la question primordiale est de savoir comment (espérons-le) vous empêcher de supprimer à nouveau votre serveur, et éviter sudo devrait être votre première ligne de défense contre cela.
David Z
2
@ WinEunuuchs2Unix Ce n'est pas du tout une question en double, l'op ici ne veut pas que la rmcommande ait un mot de passe. Ils veulent juste sudoen demander un à chaque fois que la commande rm est utilisée. La solution à la question que vous avez liée deviendrait légèrement ennuyeuse lors de votre première commande sudo rm. Comme il vous demandera deux mots de passe, un pour sudoun rm.
Dan

Réponses:

17

Vous pouvez régler la timestamp_timeoutà 0des commandes particulières dans /etc/sudoers. Créez un fichier visudo -f /etc/sudoers.d/pduckavec le contenu suivant:

Cmnd_Alias DANGEROUS = /bin/rm

Defaults!DANGEROUS timestamp_timeout=0

pduck ALL = (ALL:ALL) DANGEROUS

Désormais, l'utilisateur pduckest toujours invité à sudo rmsaisir un mot de passe lors de l'exécution (quels que soient les paramètres supplémentaires fournis), même s'il est membre du sudogroupe et se sudosouvient de son mot de passe pour les autres commandes.

L'inconvénient est que vous ne pouvez pas facilement ajouter des paramètres à la /bin/rmligne du fichier pour restreindre davantage cela. Eh bien… vous pouvez, comme:

Cmnd_Alias DANGEROUS = /bin/rm -f

mais ensuite, vous êtes simplement invité exactement sudo rm -fet non (encore) pour sudo rm -rf, par exemple.

PerlDuck
la source
9

Une méthode consisterait à utiliser safe-rm . Cela traitera UNIQUEMENT l'utilisation de "rm" et empêchera l'exécution de versions spécifiques de "rm". Cela inclut la suppression de votre système racine, mais peut également être utilisé pour empêcher la suppression des répertoires liés au système tels que "/ usr /" ou "/ var /". Depuis le lien:

Renouveler la suppression accidentelle de fichiers importants

Safe-rm est un outil de sécurité destiné à empêcher la suppression accidentelle de fichiers importants en les remplaçant /bin/rmpar un wrapper, qui vérifie les arguments donnés par rapport à une liste noire configurable de fichiers et de répertoires qui ne doivent jamais être supprimés.

Les utilisateurs qui tentent de supprimer l'un de ces fichiers ou répertoires protégés ne pourront pas le faire et un message d'avertissement s'affichera à la place:

$ rm -rf /usr   
Skipping /usr

(Les chemins protégés peuvent être définis à la fois au niveau du site et des utilisateurs.)

La récupération de fichiers importants que vous avez supprimés par erreur peut être assez difficile. Protégez-vous dès aujourd'hui en installant safe-rm et réduisez la probabilité que vous ayez besoin de contacter un service de récupération de données!

entrez la description de l'image ici

Rinzwind
la source
Vote pour la safecow
Michael Fulton
3

sudofournit une option -k, --reset-timestamp, voir man sudo:

Lorsqu'elle est utilisée conjointement avec une commande ou une option qui peut nécessiter un mot de passe, cette option obligera sudo à ignorer les informations d'identification mises en cache de l'utilisateur. Par conséquent, sudo demandera un mot de passe (si celui-ci est requis par la politique de sécurité) et ne mettra pas à jour les informations d'identification mises en cache de l'utilisateur.

Vous pouvez écrire un simple wrapper pour sudotester rm -rf /*et exécuter

sudo -k rm -rf /*

à la place, par exemple comme ceci:

sudo ()                                                                                                                                                 
{ 
    [[ "$*" == "rm -rf /*" ]] && opt="-k";
    /usr/bin/sudo $opt "$@"
}

Exemple d'utilisation

Tester avec echo aici.

$ sudo echo
[sudo] password for dessert: 

$ sudo echo

$ sudo echo a
[sudo] password for dessert: 
a
$ sudo echo a
[sudo] password for dessert: 
a

Si vous souhaitez être invité à chaque exécution rmen général, vous pouvez adapter la fonction ci-dessus comme suit:

sudo () 
{ 
    [[ "$1" == "rm" ]] && opt="-k";
    /usr/bin/sudo $opt "$@"
}

Si vous souhaitez combiner à la fois des appels de commande généraux et des lignes de commande spécifiques, je recommande d'utiliser case, par exemple:

sudo () 
{ 
    case "$*" in 
        rm*)            opt="-k" ;;
        "mv /home"*)    opt="-k" ;;
        "ln -s /usr/bin/fish /bin/sh") opt="-k" && echo "Don't you dare!" ;;
        *)              opt="" ;;
    esac;
    /usr/bin/sudo $opt "$@"
}

Notez que ces approches ne fonctionnera pas si vous exécutez sudodes options - solutions possibles [[ "$*" =~ " rm " ]]pour vérifier la chaîne « rm » entouré par des espaces ou *" rm "*)avec casepour attraper une ligne de commande contenant « rm ».

dessert
la source
[[ "$1" == "rm" ]] && opt="-k";et que diriez-vous /bin/rm?
Rinzwind
@Rinzwind Je pense que la fonction est facilement adaptable à des besoins spécifiques, en particulier l' caseapproche.
dessert
1

Cette réponse ne répond pas à la sudopartie de votre question mais d'un autre côté, elle aborde un moyen d'atténuer le danger d' rmappels accidentels pour tout utilisateur.

Vous pouvez alias rmà rm -Iqui

  • demande une confirmation dès qu'il supprimera un répertoire ou plus de 3 fichiers
  • tant que vous omettez ce-f qui remplace les -Ioptions précédentes .

--one-file-systemest une autre protection possible contre la suppression involontaire que j'utilise dans mon rmalias.

Installer

Pour créer un tel alias, utilisez la commande:

alias rm='rm -I --one-file-system'

Vous pouvez le mettre dans votre ~/.bashrcou même /etc/bash.bashrc.

Usage

$ sudo rm -r /etc/apt/sources.list.d /*
rm: remove all arguments?

Pour confirmer le type yesou sa traduction dans vos paramètres régionaux ou la première lettre de l'un des mots et appuyez sur Enter. Toute autre entrée, y compris aucune, abandonne l'opération.

David Foerster
la source