Pregunta

Ejecución de Fedora 9/10, Apache 2, PHP 5 ...

¿Puedo ejecutar una secuencia de comandos shell como root, desde un script PHP usando exec ()?

No acabo de dar Apache privilegios de root, y luego añadir "sudo" delante de ellos de comandos?

En concreto, estoy tratando de iniciar y detener un script de fondo.

Actualmente tengo un script que sólo se ejecuta la aplicación, start.sh:

#!/bin/bash 
/path/to/my/app/appname

Y un guión que mata a la aplicación, stop.sh:

#!/bin/bash 
killall appname

¿Me acaba de hacer:

<?php
exec("sudo start.sh");
?>

Gracias de antemano.

¿Fue útil?

Solución

No se puede simplemente sudo así, se necesitará crear sin contraseña sudo por primera vez en el archivo / etc / sudoers. Esto se puede hacer con el comando visudo por ejemplo. Asegúrese de configurar privilegios en sudoers de tal manera para limitar el usuario apache para que solo comando que desea ejecutar (es decir, la secuencia de comandos shell).

Incluso entonces, se plantea un riesgo para la seguridad, ya que cualquiera puede crear un script PHP y ejecutar el script de shell a su vez. Así que asegúrese de que el script de shell en sí está a salvo de alteración por el usuario de Apache.

La segunda parte, killall , es aún más problemática. Usted no sólo debe permitir que Apache para ejecutar killall con privilegios de root. Usted debe envolver killall en otro script y permitir el acceso a la de sudoers.

En el final: no ejecute Apache con la cuenta root y no utilice setuid. Tanto abrir una lata de gusanos, y ya que es un novato (dada la pregunta que hiciste) que es muy probable que se pierda algunos de los pequeños detalles que crearían problemas potenciales.

Otros consejos

  1. No ejecute Apache como root. Apache ha sido diseñado para hacer frente muy bien con el inicio como root y luego dejar caer sus privilegios tan pronto como pueda

  2. No utilice sudo en su script, ya sea - será demasiado fácil acabar con sudo misconfigured tal que cualquier secuencia de comandos que se ejecutan en su servidor se pone a correr cualquier programa que quiera con privilegios root

  3. Mira a hacer su propio programa de ejecución "setuid", de modo que consiga privilegios de root, pero luego los deja caer (al igual que lo hace Apache) cuando no los necesita más

  4. Asegúrese que el ejecutable "setuid" no se puede ejecutar por cualquier persona que no se supone que es capaz de ejecutarlo.

No soy profesional en este campo, pero parece que lo que necesita la bandera SUID.

Lea aquí para ejemplos o Google

Es necesario una capa de abstracción para proporcionar un poco de seguridad al menos! ...

A mi modo de hacer esto es escribir un simple servidor de UDP * privs con raíz en la que Python:     cuida de los paquetes UDP entrantes en un puerto dado     los compara con una lista blanca     si coinciden llevar a cabo la operación

A continuación, tiene un poco de PHP que los mensajes del servidor de Python con mensajes predefinidos ...

<?php
  $handle = fsockopen("udp://localhost",12345);
  fwrite($handle,"Start Script");
  fclose($handle);
?>

El servidor pitón relojes para los paquetes en el puerto 12345, pero simplemente ignora los que no lo son o bien "Inicio de secuencias de comandos" o "Stop escritura", ya que se ejecuta como root puede iniciar feliz su escritura del golpe. Es absolutamente necesario utilizar listas blancas sin embargo, en realidad no es seguro enviar cualquier entrada de un socket UDP a la línea de comandos directamente!

Ten en cuenta que la UDP se puede suplantar por lo que si lo permite su firewall falseadas tráfico entrante (que realmente no debería!) Cualquier persona puede enviar paquetes forjado a su servidor Python y arranque / parada de su servicio. Esto es poco probable que sea un problema, pero si no se puede reparar su cortafuegos y desea evitar que se podría volver a trabajar lo anterior a través de TCP / IP que no puede ser falsa.

Roger Heathcote.

* Es un servidor muy trivial para escribir (~ 20 líneas), pero si usted no sabe cómo entonces apenas el mensaje yo y yo lo enviará a usted o publicar aquí.

Usted no quiere dar a raíz de Apache.

Hay otra solución a su problema. El problema es que Apache no puede matar el proceso, ya que es propiedad de root. Lo que puede hacer es cambiar el propietario de 'www-data', que es lo que se identifica como Apache.

Si el proceso es un servicio y se pone en marcha en el arranque puede agregar el

sudo -u www-data <start-up script>

para que www-data sería el dueño de ese proceso y por lo tanto se ejecuta la secuencia de comandos de apagado funcionaría.

Conforme a lo solicitado, aquí está el servidor de pitón ...

#!/usr/bin/python
import os 
import socket
print "  Loading Bindings..."
settings = {}
line = 0 
for each in open('/path/to/actions.txt', 'r'):
 line = line + 1
  each = each.rstrip()
  if each <> "":
    if each[0] <> '#':
      a = each.partition(':')
      if a[2]:
        settings[a[0]] = a[2]
      else:
        print "    Err @ line",line,":",each
print "  Starting Server...",
port = 12345
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(("", port))
print "OK."
print "  Listening on port:", port
while True:
    datagram = s.recv(1024)
    if not datagram:
        break
    print "Rx Cmd:", datagram
    if settings.has_key(datagram):
      print "Launch:", settings[datagram]
      os.system(settings[datagram]+" &")
s.close() 

El archivo de configuración "actions.txt" utiliza el formato "nombre de acción: corresponde-shell-command". Es decir

# Hash denotes a comment
webroot:nautilus /var/www
ftp:filezilla
edit_homepage:gedit /var/www/homepage/htdocs/index.php

Este código no comprueba la IP de origen de los paquetes UDP entrantes como he funcionando en el servidor local, estoy un cortafuegos del de cualquier otra persona y la comprobación proporcionaría ninguna protección contra la suplantación de identidad de todos modos.

No tengo tiempo para volver a escribir para utilizar TCP / IP pero Python es un lenguaje que vale la pena conocer lo que si realmente desea que la funcionalidad Lo dejo a usted para tener un google para 'Python' y 'SOCK_STREAM'. Probablemente no sea digno de su problema, sin embargo, es más fácil de configurar el cortafuegos de modo que ningún paquete localhost falsificados pueden conseguir a través y modificar el código para asegurarse de que sólo escucha a los paquetes desde el bucle de retorno.

Se podría considerar el uso de una conexión ssh al servidor local con autenticación keepair a una cuenta que tenga permisos de root. En una configuración tal que no tendrá acceso a la raíz de su servidor web.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top