Ejecutar comandos desde las reglas de Nginx

Iniciado por WHK, 5 Mayo 2015, 21:02 PM

0 Miembros y 1 Visitante están viendo este tema.

MinusFour

Pues a mi me funciona en mi consola. ¿Sera open_basedir? ¿O quizas tu SELinux?

WHK

Pues no, aplico todos los cambios, reinicio el servidor (es centos 7) y nada, el script me dice que el id es apache y es el httpd el que está ejecutando el script en php, nginx lo único que hace es hacer de reverse proxy nada mas porque la configuración para interactuar con scripts dinámicos es mas complejo, generalmente debes usar servicios paralelos con sockets de comunicación, al final nginx nunca ejecuta finalmente el script sino el servicio de cgi, en ese caso supongo que httpd hace lo mismo pero de manera mas ordenada, nativa y automatizada, por eso mejor dejé ambos instalados.

open_basedir puede se eh, lo revisaré ahora mismo aunque por defecto debería poderse.

MinusFour

¿No te lanza ningun error? Revisa que tengas configurado PHP para lanzar errors. error_reporting y display_errors.

WHK

#13
[root@localhost ~]# tail -f /var/log/httpd/error_log
sh: /var/ban/403.sh: Permission denied
/bin/bash: /var/ban/403.sh: Permission denied
sudo: unable to open audit system: Permission denied
sudo: unable to open audit system: Permission denied


En orden sería:
Código (php) [Seleccionar]
system('/var/ban/403.sh');
# sh: /var/ban/403.sh: Permission denied

system('/bin/bash /var/ban/403.sh');
# /bin/bash: /var/ban/403.sh: Permission denied

system('sudo /var/ban/403.sh');
# sudo: unable to open audit system: Permission denied

system('sudo /bin/bash /var/ban/403.sh');
# sudo: unable to open audit system: Permission denied


Definitivamente el sudoers no funciona :( , el script en php corre con permisos de "apache" y el sudoers está habilitado para ejecutar cualquier cosa sin contraseña con sudo y nada. Cuando resulte bien dejo habilitado solo los scripts necesarios.

WHK

#14
Bueno ya busqué por algunos blogs y definitivamente el problema es el selinux tal como decías.

Intenté hacerle un bypass como se recomendaba en algunos lados pero sin éxito:
User_Alias WWW=apache
Cmnd_Alias WEBCMDS=/bin/bash /var/ban/403.sh
WWW ALL=NOPASSWD: WEBCMDS


Ahora... entiendo que por todos lados está muy restringido que un script via http se ejecute como root desde el mismo servidor hasta los sistemas de protección del mismo sistema operativo, por lo cual podría decirse que no debería hacerlo, pero entonces como lo hago si necesito que dependiendo de ciertas solicitudes http se generen acciones inmediatas a bajo nivel como cambiar la configuración de balanceos de carga, baneos por firewall, etc, no me sirve crear un log y listo, necesito que el sistema sea proactivo y rwactivo, esto quiere decir que si existe una solicitud peligrosa el usuario quede baneado al instante y no esperar a que un daemon barra un log.

En ese caso que sería mas óptimo? crear un servicio que reciba comandos? porque al final igual de todas maneras el servicio web va a tener que gatillar acciones como root, asi que no entiendo como debería hacerse sin arriesgar la seguridad de todo el sistema, no quiero tener que deshabilitar selinux.

O será que esta es una excepción a la regla?

creo que tendré que ir replanteandome si hacer esto via nginx y apache o snort directamente, veré si snort tiene la capacidad de ejecutar cosas dependiendo de cada regla.

MinusFour

#15
Bueno, es que SELinux tiene reglas mucho mas restrictivas. Siempre y cuando sepas lo que estas haciendo y entiendas las consecuencias no hay problema, claro que no siempre es posible prever todo. Yo diria que simplemente le des los permisos adecuados bajo SELinux, no veo razon por la cual no deba permitirte estando configurando propiamente.

Creo tambien que puedes pasar de Enforcing a Permissive con SELinux aunque yo creo que es preferible en enforcing sobre todo por lo que estas haciendo de configurar los contextos adecuadamente con SELinux.

Este comando cambia el type a uno que supuestamente permite apache lanzar el script:

Código (bash) [Seleccionar]

sudo chcon -t httpd_sys_script_exec_t /var/ban/403.sh

WHK

Pues si, efectivamente deja ejecutar el script pero manteniendo los permisos de apache, los que se llaman con sudo siguen sin ejecutarse :(

MinusFour

Cita de: WHK en  7 Mayo 2015, 04:15 AM
Pues si, efectivamente deja ejecutar el script pero manteniendo los permisos de apache, los que se llaman con sudo siguen sin ejecutarse :(

Porque no tienes el setuid puesto:

Código (bash) [Seleccionar]

sudo chmod 4711 /var/ban/403.sh


Si quieres usar sudo en apache vas a necesitar agregar a las politicas el typo de /usr/sbin/sudo o donde quiera que este en centos. No intentes cambiar el tipo al binario de sudo.

WHK

Bueno, para ir descartando puse selinux en modo permisivo y reinicié la maquina, ahora ejecuto:

[root@localhost ~]# su apache -s /bin/bash
bash-4.2$ id
uid=48(apache) gid=48(apache) grupos=48(apache) contexto=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
bash-4.2$ sudo id
uid=0(root) gid=0(root) grupos=0(root) contexto=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
bash-4.2$ exit
exit


Ahora si efectivamente el sudoers funciona perfectamente, pero el script en php no puede ejecutar el mismo comando a pesar de que tenga el mismo permiso. El log de errores dice:

Citarsudo: sorry, you must have a tty to run sudo

Será que debo asignarle un bash al usuario apache dentro del /etc/passwd?

MinusFour

Pruebalo con shell_exec en lugar de system.