¿Cómo aplicar siempre la contraseña de sudo para un comando específico?

12

El otro día estaba haciendo algunas tareas de mantenimiento en mi servidor web. Tenía prisa y sueño, así que hice todo usando el sudocomando.

Y luego, accidentalmente presioné Ctrl+ V, enviando este comando a mi servidor web:

sudo rm -rf /*

Para aquellos que se preguntan qué hace el comando anterior: Esto eliminó todo mi servidor web

Afortunadamente, tuve copias de seguridad y, lamentablemente, tuve que pasar dos horas más despierto para solucionar este error increíble. Pero desde entonces, me he estado preguntando:

¿Hay alguna manera de aplicar siempre la contraseña de sudo para un comando específico?

Si el servidor me pidiera una contraseña, me salvaría de muchos problemas. No lo hizo, porque ejecuté unos 5 sudocomandos antes de este majestuoso error.

Entonces, ¿hay alguna manera de hacerlo? Solo necesito la contraseña con el rmcomando para que siempre se aplique. Otros comandos que estoy usando son usualmente nanoo cpambos son (hasta cierto punto) revertables.

Pavel Janicek
fuente
1
Relacionado: Cómo hacer que sudo le
solicite
2
@solsTiCe /*se expande antes de pasar al comando rm. Entonces, el comando no ve un solo argumento, sino una lista de argumentos ( /bin /boot /cdrom /dev /etc /home...)
Dan
3
Una lección importante para sacar de esto es que no debe ejecutar las cosas con sudo a menos que realmente lo necesite. Sé que eso no responde lo que preguntaste aquí, pero la pregunta general es cómo (con suerte) evitar que elimines tu servidor nuevamente, y evitar sudo debería ser tu primera línea de defensa contra eso.
David Z
2
@ WinEunuuchs2Unix Esa no es una pregunta duplicada, el operador aquí no quiere que el rmcomando tenga una contraseña. Solo quieren sudosolicitar uno cada vez que se usa el comando rm. La solución a la pregunta que vinculaste sería un poco molesta cuando tu primer comando sea sudo rm. Como le pedirá dos contraseñas, una por sudouna rm.
Dan

Respuestas:

17

Puede establecer el timestamp_timeoutque 0los comandos particulares en /etc/sudoers. Cree un archivo visudo -f /etc/sudoers.d/pduckcon el siguiente contenido:

Cmnd_Alias DANGEROUS = /bin/rm

Defaults!DANGEROUS timestamp_timeout=0

pduck ALL = (ALL:ALL) DANGEROUS

Ahora al usuario pducksiempre se le pide una contraseña cuando se ejecuta sudo rm(sin importar qué parámetros adicionales se le den) aunque el usuario sea miembro del sudogrupo y sudorecuerde su contraseña para otros comandos.

La desventaja es que no puede agregar fácilmente parámetros a la /bin/rmlínea en el archivo para restringir aún más esto. Bueno ... puedes, como:

Cmnd_Alias DANGEROUS = /bin/rm -f

pero luego solo se le solicita exactamente sudo rm -fy no (nuevamente) sudo rm -rf, por ejemplo.

PerlDuck
fuente
9

Un método sería usar safe-rm . Esto SOLO abordará el uso de "rm" y evitará que se ejecuten versiones específicas de "rm". Eso incluye eliminar su sistema raíz, pero también puede usarse para evitar la eliminación de directorios relacionados con el sistema como "/ usr /" o "/ var /". Desde el enlace:

Evitar la eliminación accidental de archivos importantes

Safe-rm es una herramienta de seguridad destinada a evitar la eliminación accidental de archivos importantes mediante la sustitución /bin/rmde un contenedor, que comprueba los argumentos dados contra una lista negra configurable de archivos y directorios que nunca deben eliminarse.

Los usuarios que intenten eliminar uno de estos archivos o directorios protegidos no podrán hacerlo y en su lugar se les mostrará un mensaje de advertencia:

$ rm -rf /usr   
Skipping /usr

(Las rutas protegidas se pueden establecer tanto en el sitio como a nivel de usuario).

Recuperar archivos importantes que eliminó por error puede ser bastante difícil. ¡Protéjase hoy instalando safe-rm y reduzca la probabilidad de que necesite contactar un servicio de recuperación de datos!

ingrese la descripción de la imagen aquí

Rinzwind
fuente
Votado a favor de la caja fuerte
Michael Fulton
3

sudoproporciona una opción -k, --reset-timestamp, ver man sudo:

Cuando se usa junto con un comando o una opción que puede requerir una contraseña, esta opción hará que sudo ignore las credenciales almacenadas en caché del usuario. Como resultado, sudo solicitará una contraseña (si la política de seguridad la requiere) y no actualizará las credenciales almacenadas en caché del usuario.

Podría escribir un contenedor simple para sudoprobar rm -rf /*y ejecutar

sudo -k rm -rf /*

en cambio, por ejemplo, así:

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

Ejemplo de uso

Prueba con echo aaquí.

$ 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 desea que se le pregunte cada vez que ejecuta rmen general, puede adaptar la función anterior de la siguiente manera:

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

Si desea combinar tanto las llamadas de comando generales como las líneas de comando específicas, le recomiendo usar case, por ejemplo:

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 "$@"
}

Tenga en cuenta que estos enfoques no funcionarán si ejecuta sudoopciones: las posibles soluciones son [[ "$*" =~ " rm " ]]verificar la cadena "rm" rodeada de espacios o *" rm "*)con casecualquier línea de comando que contenga "rm".

postre
fuente
[[ "$1" == "rm" ]] && opt="-k";y ¿qué tal /bin/rm?
Rinzwind
@Rinzwind Creo que la función es fácilmente adaptable a necesidades específicas, especialmente el caseenfoque.
postre
1

Esta respuesta no aborda la sudoparte de su pregunta pero, por otro lado, aborda una forma de mitigar el peligro de rminvocaciones accidentales para cualquier usuario.

Puedes alias rma rm -Icual

  • pide confirmación tan pronto como elimine un directorio o más de 3 archivos
  • siempre-f que omita lo que anula las -Iopciones anteriores .

--one-file-systemes otra posible protección contra la eliminación involuntaria que uso en mi rmalias.

Preparar

Para crear dicho alias, use el comando:

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

Puedes ponerlo en tu ~/.bashrco incluso /etc/bash.bashrc.

Uso

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

Para confirmar el tipo yeso su traducción a su localidad o la primera letra de cualquier palabra y presione Enter. Cualquier otra entrada, incluida ninguna, anula la operación.

David Foerster
fuente