Domanda

Esecuzione Fedora 9/10, Apache 2, PHP 5 ...

È possibile eseguire uno script di shell come root, da uno script PHP utilizzando exec ()?

Devo solo dare Apache privilegi di root, e quindi aggiungere "sudo" davanti a loro comando?

In particolare, sto cercando di avviare e arrestare uno script di sfondo.

Attualmente ho uno script di shell che esegue semplicemente l'app, start.sh:

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

E uno script che uccide l'applicazione, stop.sh:

#!/bin/bash 
killall appname

Avrei solo fare:

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

Grazie in anticipo.

È stato utile?

Soluzione

Non si può semplicemente sudo come questo, è necessario per l'installazione senza password sudo prima nel file / etc / sudoers. Questo può essere fatto con il comando visudo per esempio. Assicurati di impostare privilegi nel file sudoers in modo tale da limitare l'utente apache a quel singolo comando che si desidera eseguire (vale a dire lo script di shell).

Anche allora, pone un rischio per la sicurezza, perché chiunque potrebbe creare uno script PHP ed eseguire lo script di shell a sua volta. Quindi, assicurarsi che shell script stesso è al sicuro da alterazione dall'utente Apache.

La seconda parte, killall , è ancora più problematico. Non si dovrebbe solo consentire ad Apache di lanciare killall con i privilegi di root. Si dovrebbe avvolgere killall in un altro script di shell e concedere l'accesso a quella sudoers.

Alla fine: non eseguire Apache con account di root e non utilizzare setuid. Entrambi aprire un vaso di Pandora, e dal momento che sei un principiante (data la domanda che hai posto) si è molto probabile di perdere alcuni dei piccoli dettagli che potrebbero creare potenziali problemi.

Altri suggerimenti

  1. Non eseguire Apache come root. Apache è stato progettato per far fronte molto bene con partenza da root e poi cadere i suoi privilegi non appena si può

  2. Non utilizzare sudo all'interno dello script sia - sarà troppo facile finire con sudo configurato male tale che ogni script in esecuzione sul server arriva a eseguire qualsiasi programma che vuole con i privilegi root

  3. Guarda rendere il proprio programma eseguito "setuid", in modo che si ottiene i privilegi di root, ma poi li lascia cadere (come Apache fa), quando non ha bisogno di loro più

  4. Assicurati che il tuo eseguibile "setuid" non può essere gestito da chi non dovrebbe essere in grado di eseguirlo.

Io non sono professionale in questo campo, ma sembra che tu abbia bisogno di bandiera SUID.

Leggi qui per esempi o Google

È necessario un livello di astrazione per fornire un po 'di sicurezza, almeno! ...

Il modo in cui lo faccio è quello di scrivere un semplice server UDP * con privs radice in Python che:     orologi per pacchetti UDP su una data porta     li confronta a una whitelist     se corrispondono effettuare l'operazione

È quindi necessario un po 'di PHP che i messaggi sul server di Python con messaggi predefiniti ...

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

Il server pitone orologi per i pacchetti sulla porta 12345, ma solo ignora quelli che non sono o "Start Script" o "Stop Script", in quanto viene eseguito come root si può tranquillamente iniziare lo script bash. È assolutamente necessario utilizzare bianco-lista, però, non è davvero sicuro di inviare qualsiasi input da un socket UDP alla riga di comando direttamente!

Da notare che UDP può essere falsificato quindi se i vostri permessi firewall contraffatti traffico in entrata (che davvero non dovrebbe!) È possibile inviare i pacchetti forgiato al server Python e fermare / avviare il servizio. Questo è improbabile che sia un problema, ma se non è possibile risolvere il tuo firewall e si vuole impedire che essa si poteva rielaborare quanto sopra utilizzando il protocollo TCP / IP che non possono essere contraffatti.

Roger Heathcote.

* E 'un server davvero banale per scrivere (~ 20 righe), ma se non si sa come poi basta messaggio me e lo invierà a voi o postare qui.

Non si vuole dare radice Apache.

C'è un'altra soluzione al vostro problema. Il problema è che Apache non può uccidere il processo perché è di proprietà di root. Che cosa si può fare è cambiare il proprietario a 'www-data', che è ciò che Apache è identificato come.

Se il processo è un servizio e si avvia al boot è possibile aggiungere il

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

in modo che www-data sarebbe il proprietario di quel processo e, quindi, l'esecuzione dello script arresto avrebbe funzionato.

Come richiesto, ecco il server python ...

#!/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() 

Il file di configurazione "actions.txt" usa l ' "azione-name: corrispondente-shell-comando" format. Cioè

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

Questo codice non controlla l'origine IP dei pacchetti UDP come ho in esecuzione su localhost, io sono di firewall di da chiunque altro e la verifica avrebbe fornito alcuna protezione contro lo spoofing in ogni caso.

Non ho il tempo di riscrivere in modo da utilizzare il protocollo TCP / IP, ma Python è un linguaggio che vale la pena di conoscere quindi se si vuole davvero che la funzionalità Lascio a voi di avere un google per 'Python' e 'SOCK_STREAM'. E 'probabilmente non vale la pena il vostro problema, però, è più facile da configurare il firewall in modo che nessun pacchetto localhost contraffatti possono ottenere attraverso e modificare il codice per assicurarsi che ascolta solo pacchetti dal loopback.

Si potrebbe considerare l'utilizzo di una connessione ssh a localhost con l'autenticazione keepair a un account che ha privilegi di root. In una tale configurazione non sarà necessario l'accesso di root per il vostro server web.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top