L'autre jour, j'effectuais des tâches de maintenance sur mon serveur Web. J'étais pressé et somnolent, alors j'ai tout fait en utilisant la commande Sudo
.
Et puis, j'ai accidentellement appuyé Ctrl+V, envoi de cette commande sur mon serveur web:
Sudo rm -rf /*
Pour ceux qui se demandent ce que la commande ci-dessus fait: Ceci a supprimé mon entier serveur Web
Heureusement, j'avais des sauvegardes et malheureusement, j'ai dû passer deux heures de plus à rester éveillé pour réparer cette erreur géniale. Mais depuis lors, je me demandais:
Y a-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 épargnerais beaucoup de problèmes. Ce n’est pas le cas, car j’ai exécuté environ 5 commandes Sudo
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 commande rm
soit toujours appliqué. Les autres commandes que j'utilise sont généralement nano
ou cp
, les deux étant (dans une certaine mesure) réversibles.
Vous pouvez définir le timestamp_timeout
sur 0
pour des commandes particulières dans /etc/sudoers
. Créez un fichier visudo -f /etc/sudoers.d/pduck
avec le contenu suivant:
Cmnd_Alias DANGEROUS = /bin/rm
Defaults!DANGEROUS timestamp_timeout=0
pduck ALL = (ALL:ALL) DANGEROUS
Désormais, l'utilisateur pduck
se voit toujours demander un mot de passe lors de l'exécution de Sudo rm
(quels que soient les paramètres supplémentaires fournis), même si l'utilisateur est membre du groupe Sudo
et Sudo
mémorise son mot de passe pour d'autres commandes.
L'inconvénient est que vous ne pouvez pas facilement ajouter des paramètres à la ligne /bin/rm
dans le fichier pour limiter cela davantage. Eh bien… vous pouvez, comme:
Cmnd_Alias DANGEROUS = /bin/rm -f
mais alors vous êtes simplement invité à indiquer exactement Sudo rm -f
et non (encore) à Sudo rm -rf
, par exemple.
Une méthode consisterait à utiliser safe-rm . Cela traitera UNIQUEMENT l'utilisation de "rm" et empêchera certaines versions de "rm" d'être exécutées. Cela inclut la suppression de votre système racine mais peut également être utilisé pour empêcher la suppression de répertoires liés au système tels que "/ usr /" ou "/ var /". À partir du lien:
Réapparition de la suppression accidentelle de fichiers importants
Safe-rm est un outil de sécurité destiné à empêcher la suppression accidentelle de fichiers importants en remplaçant
/bin/rm
par un wrapper, qui compare les arguments donnés à 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 au niveau du site et de l'utilisateur.)
La récupération de fichiers importants que vous avez supprimés par erreur peut être assez difficile. Protégez-vous aujourd'hui en installant safe-rm et réduisez le risque de devoir contacter un service de récupération de données!
Sudo
fournit une option -k, --reset-timestamp
, voir man Sudo
:
Lorsqu'elle est utilisée avec une commande ou une option pouvant nécessiter un mot de passe, cette option fera en sorte que Sudo ignore les informations d'identification mises en cache de l'utilisateur. En conséquence, Sudo demandera un mot de passe (si un mot de passe 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 Sudo
testing pour rm -rf /*
et en cours d'exécution.
Sudo -k rm -rf /*
à la place, par exemple comme ça:
Sudo ()
{
[[ "$*" == "rm -rf /*" ]] && opt="-k";
/usr/bin/Sudo $opt "$@"
}
Test avec echo a
ici.
$ 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 voulez qu'on vous demande chaque fois que vous exécutez rm
en 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 des appels de commande généraux et des lignes de commande spécifiques, nous vous recommandons d'utiliser case
name__, 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 fonctionneront pas si vous exécutez Sudo
avec des options. Les solutions possibles sont [[ "$*" =~ " rm " ]]
pour rechercher la chaîne "rm" entourée d'espaces ou *" rm "*)
avec case
pour intercepter toute ligne de commande contenant "rm".
Cette réponse n'aborde pas la partie Sudo
de votre question, mais en revanche, elle indique un moyen d'atténuer le risque d'appels accidentels rm
pour any utilisateur.
Vous pouvez alias rm
à rm -I
qui
-f
qui annule les options précédentes de -I
.--one-file-system
est une autre protection possible contre la suppression involontaire que j'utilise dans mon alias rm
name__.
Pour créer un tel alias, utilisez la commande:
alias rm='rm -I --one-file-system'
Vous pouvez le mettre dans votre ~/.bashrc
ou même /etc/bash.bashrc
.
$ Sudo rm -r /etc/apt/sources.list.d /*
rm: remove all arguments?
Pour confirmer, tapez yes
ou sa traduction dans votre langue ou la première lettre de Word, puis appuyez sur Enter. Toute autre entrée, y compris aucune, annule l'opération.