Запуск Fedora 9/10, Apache 2, PHP 5 …
Могу ли я запускать сценарий оболочки как root из сценария PHP с помощью exec ()?
Я просто даю Apache root priveleges, а затем добавляю команду «sudo» перед ними?
В частности, я пытаюсь запустить и остановить фоновый скрипт.
В настоящее время у меня есть сценарий оболочки, который просто запускает приложение, start.sh:
#!/bin/bash /path/to/my/app/appname
И скрипт, который убивает приложение, stop.sh:
#!/bin/bash killall appname
Я бы просто сделал:
<?php exec("sudo start.sh"); ?>
Заранее спасибо.
Вы не можете просто так судиться, вам нужно сначала настроить sudo без пароля в файле / etc / sudoers. Это можно сделать с помощью команды visudo, например. Убедитесь, что вы настроили привилегии в файле sudoers таким образом, чтобы ограничить пользователя apache той единственной командой, которую вы хотите запустить (т. Е. Скриптом оболочки).
Даже тогда он создает угрозу безопасности, потому что любой может создать скрипт PHP и запустить сценарий оболочки по очереди. Поэтому убедитесь, что сам сценарий оболочки защищен от изменения пользователем Apache.
Вторая часть, killall , еще более проблематична. Вы не должны просто разрешать Apache запускать killall с привилегиями root. Вы должны обернуть killall в другой сценарий оболочки и предоставить доступ к этому в sudoers.
В конце концов: не запускайте Apache с учетной записью root и не используйте setuid. Как открыть банку червей, так как вы новичок (учитывая заданный вами вопрос), вы, скорее всего, пропустите некоторые мелкие детали, которые создадут потенциальные проблемы.
Не запускайте Apache как root
. Apache был разработан, чтобы очень хорошо справляться с запуском с root
а затем сбрасывать свои привилегии как можно скорее
Не используйте sudo
в своем скрипте – слишком сложно закончить с sudo
неправильно сконфигурированным, чтобы любой скрипт, запущенный на вашем сервере, запускал любую программу, которая ему нравится, с привилегиями root
Посмотрите, как сделать свою собственную программу «setuid», чтобы она получала привилегии root, но затем бросает их (как и Apache), когда она больше не нуждается в них
Убедитесь, что ваш исполняемый файл setuid не может быть запущен любым, кто не должен его запускать.
Я не профессионал в этой области, но похоже, что вам нужен флаг SUID.
Ознакомьтесь с примерами или google
Вам нужен слой абстракции, чтобы обеспечить минимальную безопасность! …
То, как я это делаю, – написать простой UDP-сервер * с корневыми привилегиями в Python, который: следит за входящими пакетами UDP на данном порту, сравнивает их с белым списком, если они совпадают, выполняют операцию
Тогда у вас есть немного PHP, который сообщает сервер Python с заранее определенными сообщениями …
<?php $handle = fsockopen("udp://localhost",12345); fwrite($handle,"Start Script"); fclose($handle); ?>
Сервер python наблюдает за пакетами на порту 12345, но просто игнорирует любые, которые не являются «Start Script» или «Stop Script», так как он запускается с правами root, он может с радостью запустить ваш скрипт bash. Вы, АБСОЛЮТНО ДОЛЖНЫ использовать белую листинг, хотя, ДЕЙСТВИТЕЛЬНО НЕ БЕЗОПАСНО отправлять ЛЮБОЙ вход из гнезда UDP в командную строку напрямую!
Обратите внимание, что UDP может быть подделан, поэтому, если ваш брандмауэр разрешает поддельный входящий трафик (он действительно не должен!), Кто-то мог отправлять поддельные пакеты на ваш сервер Python и останавливать / запускать вашу службу. Это вряд ли будет проблемой, но если вы не можете исправить свой брандмауэр, и вы хотите защитить его, вы можете переработать выше, используя TCP / IP, который нельзя подделать.
Роджер Хиткоут.
* Это действительно тривиальный сервер для написания (~ 20 строк), но если вы не знаете, как тогда просто отправить сообщение мне, и я отправлю его вам или отправлю его здесь.
Вы не хотите давать Apache root.
Есть еще одно решение вашей проблемы. Проблема в том, что Apache не может убить процесс, потому что он принадлежит root. Что вы можете сделать, так это изменить владельца на «www-data», который идентифицирует Apache.
Если процесс является сервисом и запускается при загрузке, вы можете добавить
sudo -u www-data <start-up script>
так что www-data будет являться владельцем этого процесса и, следовательно, будет работать сценарий shut-down.
В соответствии с запросом, вот сервер 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()
Конфигурационный файл «actions.txt» использует формат «action-name: соответствующий-shell-command», т.е.
# Hash denotes a comment webroot:nautilus /var/www ftp:filezilla edit_homepage:gedit /var/www/homepage/htdocs/index.php
Этот код не проверяет исходный IP-адрес входящих пакетов UDP, поскольку я запускаю его на локальном хосте, я брандмауэр от кого-либо еще, и проверка не обеспечит никакой защиты от подмены.
У меня нет времени переписывать его для использования TCP / IP, но Python – это язык, который стоит узнать, поэтому, если вы действительно хотите эту функциональность, я оставлю это вам, чтобы иметь Google для «Python» и «SOCK_STREAM», , Вероятно, это не стоит вашей проблемы, проще настроить брандмауэр, чтобы никакие поддельные пакеты localhost не могли пройти и изменить код, чтобы убедиться, что он только прослушивает пакеты из loopback.
Вы можете рассмотреть возможность подключения ssh к localhost с помощью проверки подлинности keepair учетной записи с правами root. В такой настройке вам не нужен root-доступ для вашего веб-сервера.