No se puede establecer el UID en los scripts de Shell

14

¿Alguien puede ayudarme a descubrir qué está pasando aquí? Tengo algunas reglas para configurar el conteo de paquetes de seguimiento. Cuando ejecuto el siguiente script como root:

#!/bin/bash
iptables -t mangle -xnvL

Obtengo el resultado que espero:

//snip
233203 199929802 MARK  //blah blah blah
//snip

Sin embargo, quiero ejecutar esto como parte de cactus, que se ejecuta como apache. Ahora apache no puede ejecutar iptables, por eso tengo el script. Lo configuré como raíz SUID :

-rwsr-sr-x 1 root root   37 May 14 23:06 iptables_packet_report.sh

Pero luego obtengo esta salida:

server # sudo -u apache ./iptables_packet_report.sh
iptables v1.4.2: can't initialize iptables table `mangle': Table does not exist (do you need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.

Obviamente mi kernel está bien, y el hecho de que lo estoy ejecutando como no root está arruinando algo, pero no entiendo por qué. Verifiqué dos veces el SUID con [la demostración] ( http://en.wikipedia.org/wiki/Setuid#Demonstration y confirme que estaba funcionando.

server # sudo -u apache ./printid
Real UID  = 81
Effective UID = 0
Real GID  = 81
Effective GID = 0

Mi objetivo final es obtener la salida de iptables -t mangle -xnvL mientras se ejecuta como apache para poder usar cactus para graficarlo todo muy bien.

Tom Ritter
fuente

Respuestas:

16

No puede usar la raíz SUID para los scripts de shell. Solo los programas reales pueden ser raíz SUID, los scripts de shell comienzan con "#!" y el intérprete tendría que ejecutar SUID y eso no funciona por alguna razón que no sabía

¡Eche un vistazo a sudo e instálelo! Edite / etc / sudoerrs, agregue una línea como esta:

www-data        ALL=NOPASSWD: /usr/local/sbin/iptables_packet_report.sh

Entonces solo corre

sudo /usr/local/sbin/iptables_packet_report.sh

de tu código

Entonces no debe solicitar la contraseña, sino evaluar el proceso automáticamente.

Estoy bastante seguro de que sus mensajes de error también aparecerían si ingresa manualmente a www-data y lo ejecuta manualmente

cristiano
fuente
13

Como Christian indicó, mi problema era que estaba tratando de SUID en un script de shell. Como se explica aquí, configurar SUID en un script de shell es una muy mala idea:

ejecutar un script de shell en UNIX implica un proceso de dos pasos: cuando el kernel determina que un script de shell está a punto de ejecutarse, primero inicia una copia SUID del intérprete de shell, luego el intérprete de shell comienza a ejecutar el script de shell. Debido a que estas dos operaciones se realizan en dos pasos discretos, puede interrumpir el núcleo después del primer paso y cambiar el archivo que el intérprete de shell está a punto de ejecutar. De esta manera, un atacante podría hacer que la computadora ejecute cualquier script de shell de su elección

Debido a esto, muchas distribuciones modernas de Linux ignoran los scripts de shell SUID, incluido gentoo que estaba usando. Pude editar el archivo sudoers y lo hice funcionar.

Tom Ritter
fuente
Fantástica respuesta!
Dave Cheney
Alguien sabe si esto es cierto para Solaris 10?
Eric Johnson el
2

Creo que la solución de christian es la mejor, pero si realmente quisieras, puedes compilar el script usando shc y luego configurar la raíz en el programa compilado.

Kyle Brandt
fuente