¿Debo usar sudo en un script o sudo en un script completo?

¿Debo usar sudo en un script o sudo en un script completo?

Manejo un pequeño grupo de máquinas macOS para estudiantes (digamos 20) y todas deben configurarse con cosas como homebrew y otros paquetes y aplicaciones. Estoy escribiendo un script bash para instalar automáticamente todo lo necesario en cada computadora. Algunos de los comandos que usaré requieren ser ejecutados como root, pero no la mayoría.

Me preguntaba si sería mejor sudo individualmente cada uno de estos comandos en el script, o dejar sudo fuera del script y sudo todo el script. Me gustaría saber cuál será más seguro (en cuanto a seguridad) y mejor para mi situación. Preferiría que no me solicitaran una contraseña en todo el script, pero tampoco quiero ejecutar cada línea del script como root, ya que no es seguro.

Respuesta1

Siguiendo el principio de privilegio mínimo, ejecute lo menos que pueda como root. Por lo tanto, sudo desde dentro del script.

Tenga en cuenta que la primera vez que haya un comando que necesite sudo, es posible que se le solicite. (Eso no será cierto si utiliza NOPASSWD en /etc/sudoers, que es una técnica que muchas personas evitarán por ser insegura). Sin embargo, cuando ejecuta sudo y proporciona una contraseña, sudo recordará el éxito de un período de tiempo. Por defecto ese periodo de tiempo es de cinco minutos. Entonces, si ejecutó "sudo echo hi", escribió su contraseña y luego ejecutó el script poco después, no sería necesario que se le solicite una contraseña cuando ejecute el script. De manera más realista, si simplemente ejecuta el script, probablemente se le pedirá que haga sudo una vez... suponiendo que su script tarde menos de unos minutos en completar las tareas restantes.

Puede que no me preocupe por algunos echocomandos, pero si hay contenido importante que se puede hacer sin permisos adicionales, entonces, por razones de seguridad, generalmente prefiero maximizar cuánto se hace con una elevación mínima.

Como ejemplo de cómo minimizar permisos, permítame mostrarle otro escenario de muestra. En lugar de:
sudo -c "sample-command >> /var/log/output.txt"

Me gusta usar:
sample-command | sudo tee -a /var/log/output.txt >> /dev/null

Al hacer esto, todo el comando se ejecuta sin sudo, y la única parte que termina teniendo permisos mejorados es la parte que necesita permisos mejorados, que es la parte que escribe en el archivo.

Claramente, mi objetivo aquí es minimizar cuánto se hace elevado. De manera similar, si todo su script no requiere elevación, el enfoque preferido (desde una perspectiva de seguridad) es minimizar cuánto se hace elevado.

Respuesta2

Depende de cuáles sean los comandos. Para los comandos que se descargan de Internet, es mejor no ejecutarlos como root. Pero el otro comando debería poder ejecutarse como root. Lo que haría es separar el comando en dos scripts: uno para comandos no root y otro para comandos root.

Quizás podría ayudar más si pudiera obtener la lista de comandos.

Respuesta3

Por lo general, (supongo) querrás que el script se trate como cualquier otro comando/aplicación/utilidad. En cuyo caso, normalmente no se le solicitará una contraseña para aumentar sus privilegios; simplemente se le negará y recibirá un error. Algo como:
Permission denied, oOperation not permitted.

Pero usted mencionó específicamente que usted:
"...no quiero ejecutar todas las líneas del script como root..."
Así que realmente no veo una alternativa a la invocación explícita y exclusiva sudoen/desde líneas de código específicas donde sea relevante.

También mencionaste que:
"...prefiero que no se le solicite una contraseña durante todo el script..."
Y lo más probable es que no lo hagas. No se le avisará cada vez que se invoque sudo a menos que pase una cantidad significativa de tiempo entre operaciones.

Respuesta4

Aquí hay una solución: ejecute el script rootusando sudoy ejecute cualquier comando que no requiera privilegios elevados como el usuario original usando sudo -u $SUDO_USER <command>.

Aquí hay un script de ejemplo example.sh:

#!/bin/bash

if [ "$(whoami)" != "root" ] ; then
    echo "Run this script with sudo" >&2
    exit 1
fi

sudo -u "${SUDO_USER:-$USER}" this_command_run_as_user
this_command_run_as_root
this_command2_run_as_root

Lo ejecutarías así:

sudo ./example.sh

La ventaja de hacerlo de esta manera es que la contraseña del usuario sólo se solicitará como máximo una vez al inicio del script. No necesita preocuparse por los tiempos de espera para sudo.

información relacionada