Mejores prácticas sobre el uso de sudo en un script bash

11

Tengo un script bash de larga y larga ejecución donde un puñado de comandos deben ejecutarse como root, mientras que la mayoría de los comandos deben ejecutarse como el usuario normal antes de sudo, ya que estropearía la propiedad del archivo y demás.

Se me ocurrieron algunos métodos, pero cada uno de ellos tiene algunos problemas.

Método 1: usar sudo dentro del archivo

#!/bin/bash
sudo echo "I must be run by root"
touch needsToBeOwnedByUser1
echo "needs to be run by user"
sleep 1000
sudo echo "I, again, must be run by root"

Esto se vería bien, por la forma en que está escrito el código. sudoestá escrito antes de las pocas declaraciones que realmente deben ejecutarse por root, pero si el tiempo entre cada sudollamada es demasiado largo, sudonuevamente solicita una contraseña. Además, si la primera ejecución de sudofalla, por ejemplo, debido a una contraseña no válida, el resto del script aún se ejecuta.

Método 2: usar sudo para llamar al archivo y luego volver al usuario original cuando sea necesario

#!/bin/bash
echo "I must be run by root"
su username -c 'touch needsToBeOwnedByUser1'
su username -c 'echo "needs to be run by user"'
su username -c 'sleep 1000'
echo "I, again, must be run by root"

Esto también apesta, porque necesito agregar su username -cdelante de casi todas las líneas. También sudoes posible encontrar el nombre de usuario original después , pero engorroso.

¿Hay una mejor manera?

Editar: solo publiqué pequeños guiones sin sentido aquí para mostrar de lo que estoy hablando. En la secuencia de comandos real, tengo algunas líneas que necesitan sudo (iniciar y detener servicios), algunas líneas donde no importa si hay sudo y muchas líneas que realmente necesitan ejecutarse sin sudo.

Dakkaron
fuente
44
Esto es muy raramente necesario. En la mayoría de los casos, simplemente ejecuta el script con sudosi necesita tener permisos elevados. Pero no tiene sentido cambiar su username -ca ejecutar un echo. En otras palabras, esto suena como un [XY]. ¿Podría editar y explicar qué hará realmente su script y por qué siente que necesita cambiar de usuario con tanta frecuencia?
terdon
1
@ElderGeek, ¿pegaste el enlace incorrecto? Eso ni siquiera parece estar relacionado. Probablemente sea un duplicado de ¿Cómo ejecuto el comando 'sudo' dentro de un script? pero espero que el OP pueda explicar un poco más.
terdon
@terdon Parece que sí. Limpiar.
Élder Geek
Este es solo un script de ejemplo. No quería pegar un script de más de 200 líneas aquí. Editaré la respuesta para más detalles.
Dakkaron
¿Ha considerado la opción de validación, que se describe en man sudo? -v, --validate 'Actualice las credenciales almacenadas en caché del usuario, autenticándolo si es necesario. Para el complemento sudoers, esto extiende el tiempo de espera de sudo por otros 15 minutos de forma predeterminada, pero no ejecuta un comando. No todas las políticas de seguridad admiten credenciales almacenadas en caché '. (Si lo ejecuta con la frecuencia suficiente, la autenticación de sudo no debería
expirar

Respuestas:

5

Con respecto al método 2, es más fácil usar una función. Por ejemplo:

#!/bin/bash

func(){
    echo "Username: $USER"
    echo "    EUID: $EUID"
}

export -f func

func
su "$SUDO_USER" -c 'func'

$SUDO_USERes el nombre de usuario del sudoer. También podría usar $(logname)en su lugar.

Corriendo en mi máquina:

$ sudo bash test.sh
[sudo] password for wja: 
Username: root
    EUID: 0
Username: wja
    EUID: 1000
wjandrea
fuente
2

Al leer man sudoers, uno ve:

 PASSWD and NOPASSWD

   By default, sudo requires that a user authenticate him or herself
   before running a command.  This behavior can be modified via the
   NOPASSWD tag.  Like a Runas_Spec, the NOPASSWD tag sets a default for
   the commands that follow it in the Cmnd_Spec_List.  Conversely, the
   PASSWD tag can be used to reverse things.  For example:

   ray     rushmore = NOPASSWD: /bin/kill, /bin/ls, /usr/bin/lprm

   would allow the user ray to run /bin/kill, /bin/ls, and /usr/bin/lprm
   as root on the machine rushmore without authenticating himself. 

Por lo tanto, podría permitir que regularel host se machine1ejecute command1y command2como root, sin autenticación de contraseña con:

reguser machine1 root = NOPASSWD: /usr/local/command1, /usr/local/command2  

pero lea cada uno man -k sudopara más detalles.

Waltinator
fuente
0

Quizás esto pueda ayudar:

chmod 775 yourscript.sh

Luego puede usar sudo dentro del script (sin solicitud de contraseña) y no puede usar sudo para otros comandos dentro de su script.

1337 HaXxoR
fuente
Me temo que eso no funciona. chmod 775solo le permite ejecutar el archivo y no cambia el usuario que está ejecutando el archivo o sus derechos.
Dakkaron