2011-05-03 8 views
7

He hecho un script de bash simple que necesita mantener sus privilegios de superusuario en todo el script. Desafortunadamente, pero comprensible, la secuencia de comandos pierde sus permisos sudo -eleveted cuando se produce el sleep. No es bueno para mí:Guión de shell - Permisos de sudo perdidos en el tiempo

sudo echo "I am sudo!" # Asks for passwords 
sleep(60) 
sudo echo "I am sudo!" # Need to enter password again. 

pensé en sustitución de la sleep con un bucle while que mantiene el sudo vivo, pero estoy bastante seguro de que hay mejores opciones disponibles para hacer las sudo -Permissions permanecen durante todo el guión?

Gracias

+2

¿por qué no dejas que el usuario lo ejecute 'sudo'? – CharlesB

Respuesta

10

La flexibilidad de sudo es ampliamente subestimado. Esto lleva a prácticas muy pobres (como el método de cirugía de canon ball sudo su -).

Un método mucho mejor es permitir especificamente los comandos que la intención de permitir que sin el uso de una contraseña:

phill = NOPASSWD: /bin/ls, /usr/bin/lprm 

Usted puede hacer opcionalmente esto para los usuarios específicos de determinados hosts funcionando como usuarios administradores específicos. Incluso puede evitar que los usuarios pasen escapes de shell como parámetros. Puede hacer que sudo evite que el programa iniciado ejecute otras aplicaciones dinámicamente, etc., etc. Deseará read the man-page for sudoers (and be sure to read the procedures for editing this special file!).

Aquí está una pequeña muestra de las cosas, (from here):

User_Alias  OPERATORS = joe, mike, jude 
Runas_Alias OP = root, operator 
Host_Alias  OFNET = 10.1.2.0/255.255.255.0 
Cmnd_Alias  PRINTING = /usr/sbin/lpc, /usr/bin/lprm 

OPERATORS ALL=ALL 
#The users in the OPERATORS group can run any command from any terminal. 

linus ALL=(OP) ALL 
# The user linus can run any command from any terminal as any user in the OP group (root or operator). 

user2 OFNET=(ALL) ALL 
# user user2 may run any command from any machine in the OFNET network, as any user. 

user3 ALL= PRINTING 
# user user3 may run lpc and lprm from any machine. 

go2linux ALL=(ALL) ALL 
# user go2linux may run any command from any machine acting as any user. (like Ubuntu) 

If you want not to be asked for a password use this form 
go2linux ALL=(ALL) ALL NO PASSWD: ALL 
5

Puede ajustar este tiempo de espera mediante la adición a/etc/sudoers

Defaults timestamp_timeout=#Number of minutes 

pero es mucho más fácil de ejecutar

sudo ./worker.sh 
4

Aquí hay una solución:

sudo echo "I am sudo!" # Asks for passwords 
(while true; do sudo -v; sleep 40; done) & # update the user's timestamp 
sudoPID=$! 
# ... 
sleep(60) 
sudo echo "I am sudo!" # Need to enter password again. 
kill -TERM $sudoPID 
sudo -k # invalidate the user's timestamp at end of script (does not require a password) 
+2

Si va a hackearlo de esa manera, AL MENOS asegúrese de que kill y 'sudo -k' están registrados como trampas de señal en su script. Esto está pidiendo grandes agujeros de seguridad. (abortar secuencia de comandos con Ctrl-C, sudo guardado en silencio de forma indefinida) – sehe

0

Obtener la Root privilegios de una vez por todas:

sudo su - 
# What I need to do with root 
2

Esto a mi manera:

#!/bin/sh 
echo "Working..." 
# add you pass 
echo "yourpass" >> file.pass ;sleep 5 
# Check if root 
if [ `cat file.pass | sudo -S su root -c whoami` != "root" ]; then 
echo "Not running as root. Exiting..." 
sleep 2 
echo "Cleaning..." 
sleep 1 
srm file.pass 
echo "Cleaned" 
exit 0 
else 
echo "Running as root. Good" 
sleep 2 
# and run any sudo with 
cat file.pass | sudo -S su root -c ls #<any command> 
fi 

sleep 5 
echo `cat file.pass | sudo -S su root -c whoami` "say bay bay" 
# if pass no longer need 
srm file.pass 
echo "End session :)" 
exit 0 
+1

Parece una respuesta válida, pero guardar la contraseña del usuario en un archivo parece bastante inseguro. Además, ¿qué hace el comando 'srm'? Mi distribución de Linux no lo tiene. –

2

Trabajar estrictamente dentro de un script (y no editar el archivo sudoers o llamar al script a través de sudo ./script.sh), esto es lo que creo que es el método más limpio.

startsudo() { 
    sudo -v 
    (while true; do sudo -v; sleep 50; done;) & 
    SUDO_PID="$!" 
    trap stopsudo SIGINT SIGTERM 
} 
stopsudo() { 
    kill "$SUDO_PID" 
    trap - SIGINT SIGTERM 
    sudo -k 
} 

Básicamente, esto define un par de funciones para habilitar y deshabilitar el modo sudo. Llamando al startsudo antes de ejecutar su código sudo-using se autentica con sudo, crea un bucle de sudo-refrescante de fondo, guarda el PID del bucle y establece una trampa de señal para detener el modo sudo cuando se presiona Ctrl + C. Llamar al stopsudo elimina el bucle, borra la trampa de señal e invalida la autenticación anterior con sudo.

Después de copiar estas funciones en su secuencia de comandos, utilícelas de esta manera.

startsudo 
echo "Sudo mode is active." 
# whatever you want to do with sudo 
stopsudo 

Me gustaría dar las gracias @karl por la sencillez de inlining el bucle y @sehe sudo-refrescante para señalar que una trampa de la señal debe ser usado para matar el bucle si no se mata normalmente. Ambas ideas mejoraron my btrfs backup script, que usa un bucle sudo-refreshing para evitar volver a solicitar al usuario después de que la copia de seguridad de un subvolumen demora más que el tiempo de espera de sudo.

Cuestiones relacionadas