Nasıl bir PHP komut dosyası kök olarak bir kabuk çalıştırmak olabilir?

7 Cevap php

Fedora 9/10, Apache 2, PHP 5 Koşu ...

Ben exec kullanarak bir PHP komut dosyası () dan, root olarak bir kabuk çalıştırabilir miyim?

Ben sadece Apache kök ayrıcalığa vermek, ve sonra onları komuta önünde "sudo" eklerim?

Özellikle, bir arka plan komut dosyasını başlatmak ve durdurmak için çalışıyorum.

Şu anda, sadece app çalışan bir kabuk komut dosyası var start.sh:

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

Ve app, stop.sh öldüren bir komut:

#!/bin/bash 
killall appname

Ben sadece yapardı:

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

Şimdiden teşekkürler.

7 Cevap

Sadece böyle Sudo değil, ilk kurulum şifresiz sudo gereken / etc / sudoers dosyasında. Bu, örneğin visudo komutu ile yapılabilir. Eğer (yani kabuk komut dosyası) çalıştırmak isteyen bu tek komuta apache kullanıcıyı sınırlamak için bu şekilde sudoers dosyasındaki ayrıcalıklarını ayarlamak emin olun.

Herkes bir PHP komut dosyası oluşturmak ve sırayla kabuk komut dosyası çalıştırabilir, çünkü o zaman bile, bir güvenlik riski oluşturur. Yani kabuk script kendisi, Apache kullanıcı tarafından değiştirilebilir güvenli olduğundan emin olun.

İkinci bölüm, killall, daha problemlidir. Sadece Apache root yetkileri ile killall çalışmasına izin vermemelidir. Sen başka bir kabuk komut Killall sarın ve sudoers bu erişim izni vermelidir.

Sonunda: root hesabı ile Apache çalıştırmak vermez ve setuid'dir kullanmayın. Hem solucanlar bir kutu açın ve (eğer sorulan soruya verilen) bir acemi beri potansiyel sorunlar yaratacak küçük ayrıntılar bazı özledim çok muhtemeldir.

  1. root olarak Apache çalıştırmak etmeyin. Apache root olarak başlayan ve daha sonra sadece en kısa sürede olabildiğince kendi ayrıcalıkları bırakarak ile çok iyi başa çıkmak için tasarlanmıştır

  2. Lütfen komut ya içinde sudo kullanmayın - bu sudo sunucu üzerinde çalışan herhangi bir komut ile o seviyor herhangi bir programı çalıştırmak için alır böyle yanlış yapılandırılmış ile sonuna kadar çok kolay olacak root ayrıcalıklar

  3. Bir daha onlara ihtiyacınız olmadığında root haklarını alır, ama sonra (Apache yaptığı gibi) onları düşer, böylece "setuid" kendi program akışını hale bak

  4. Lütfen "setuid" çalıştırılabilir çalıştırmak mümkün olması gerekiyordu değil herkes tarafından işletilen olamaz emin olun.

Ben bu alanda profesyonel değilim, ama SUID bayrak gerekir gibi görünüyor.

examples için buraya okumak veya google

Sen en azından küçük bir güvenlik sağlamak için bir soyutlama katmanı ihtiyacım var! ...

The way I do this is to write a simple UDP server* with root privs in Python which: watches out for incoming UDP packets on a given port compares them to a whitelist if they match carry out the operation

Daha sonra önceden tanımlanmış mesajlar ile PHP bu mesajları Python sunucu biraz var ...

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

Python sunucu portu 12345 üzerindeki paketler için saatler ama sadece o mutlulukla betik başlayabilirsiniz root olarak çalışır gibi, "Başlat Senaryo" ya da "Dur Senaryo" ya da değildir herhangi sayar. Sen KESİNLİKLE rağmen beyaz liste kullanmak zorundadır, doğrudan komut satırına bir UDP soket HERHANGİ girdi göndermek için GERÇEKTEN GÜVENLİ DEĞİLDİR!

UDP yani sahte olabilir dikkat musunuz duvarı izin (o gerçek değil gerektiğini!) Birisi hizmetini başlatmak / Python sunucu sahte paketleri göndermek ve durdurabilir gelen trafik sahte eğer. Bu bir sorun olması pek mümkün değildir ancak güvenlik duvarı tamir edemez ve buna karşı korunmak istiyorsanız eğer sahte olamaz yukarıdaki kullanarak TCP / IP yeniden işleme olabilir.

Roger Heathcote.

* O (~ 20 satır) yazmak için gerçekten önemsiz sunucu ama sonra sadece bana mesaj ve ben size göndereceğiz veya buradan sonrası için nasıl bilmiyorum.

Talep olarak, burada python sunucusu bulunuyor ...

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

Yani: config dosyası "actions.txt" format "gelen-kabuk-komut aksiyon-adını kullanır"

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

Ben localhost üzerinde çalışan gibi bu kod, gelen UDP paketlerinin kaynak IP kontrol etmez, ben herkesten bir güvenlik duvarı yaşıyorum ve kontrol yine sızdırma karşı koruma sağlayacaktır.

Ben TCP / IP kullanmak için yeniden yazmak için zaman yok ama Python gerçekten işlevsellik istiyorsanız eğer öyleyse ben 'Python' ve 'SOCK_STREAM' için bir google var size bırakacağım tanımaya değer bir dildir . Hiçbir sahte localhost paketleri yoluyla almak ve emin sadece loopback alınan paketlerin dinler yapmak için kodunu değiştirmek böylece bu güvenlik duvarı yapılandırmak için kolay, ama muhtemelen sorun değmez.

Apache kök vermek istemiyorum.

Senin sorunun başka bir çözüm var. Sorun sahibi root olduğundan Apache süreci öldürmek değil ki. Ne yapabilirim Apache olarak tespit budur 'www-data' için sahibini değiştirmektir.

İşlemin bir hizmet olduğunu ve açılışta başlar Eğer ekleyebilirsiniz

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

böylece www-data bu sürecin sahibi olacak ve dolayısıyla kapatma komut dosyası çalıştıran çalışacak.

Root izinlerine sahip bir hesaba keepair kimlik doğrulaması ile Localhost'a bir ssh bağlantısı kullanarak düşünebiliriz. Böyle bir kurulumda size sunucusu için kök erişim gerekmez.