Подтвердить что ты не робот

Начиная FOREVER или PM2 как WWW-DATA с PHP скрипт

У меня есть nodejs script с именем script.js.

var util = require('util'); 
var net = require("net"); 

process.on("uncaughtException", function(e) {
console.log(e);
});

var proxyPort = "40000"; 
var serviceHost = "1.2.3.4"; 
var servicePort = "50000"; 

net.createServer(function (proxySocket) {
    var connected = false;
    var buffers = new Array();
    var serviceSocket = new net.Socket();
    serviceSocket.connect(parseInt(servicePort), serviceHost);
    serviceSocket.pipe(proxySocket).pipe(serviceSocket);
    proxySocket.on("error", function (e) {
        serviceSocket.end();
    });
    serviceSocket.on("error", function (e) {
        console.log("Could not connect to service at host "
            + serviceHost + ', port ' + servicePort);
        proxySocket.end();
    });
    proxySocket.on("close", function(had_error) {
        serviceSocket.end();
    });
    serviceSocket.on("close", function(had_error) {
        proxySocket.end();
    });
}).listen(proxyPort);

Я запускаю его обычно как nodejs script.js, но теперь я хочу включить функции forever или pm2. Когда я root все работает смутно:

chmod -R 777 /home/nodejs/forever/;
-- give rights

watch -n 0.1 'ps ax | grep forever | grep -v grep'
-- watch forwarders (where i see if a forever is opened)

/usr/local/bin/forever -d -v --pidFile "/home/nodejs/forever/file.pid" --uid 'file' -p '/home/nodejs/forever/' -l '/home/nodejs/forever/file.log' -o '/home/nodejs/forever/file.log' -e '/home/nodejs/forever/file.log' -a start /etc/dynamic_ip/nodejs/proxy.js 41789 1.2.3.4:44481 414 file
-- open with forever

forever list
-- it is there, i can see it

forever stopall
-- kill them all

Проблема в том, что я хочу запустить script с PHP script с помощью функций system или exec:

sudo -u www-data /usr/local/bin/forever -d -v --pidFile "/home/nodejs/forever/file.pid" --uid 'file' -p '/home/nodejs/forever/' -l '/home/nodejs/forever/file.log' -o '/home/nodejs/forever/file.log' -e '/home/nodejs/forever/file.log' -a start /etc/dynamic_ip/nodejs/proxy.js 41789 1.2.3.4:44481 414 file
-- open as www-data (or i can do this just by accessing `http://1.2.3.4/test.php`, it is the same thing)

forever list
-- see if it is there, and it is not (i see it in watch)

forever stopall
-- says no forever is opened

kill PID_ID
-- the only way is to kill it by pid ... and on another server all of this works very well, can create and kill forevers from a PHP скрипт when accessing it from web ... not know why
-- everything is in /etc/sudoers including /usr/local/bin/forever 

Почему? Как я могу это решить?

Я также сделал несколько трюков, создал пользователя 'forever2', я создал script.sh с этим контентом:

sudo su forever2 user123; /usr/local/bin/forever -d -v --pidFile "/home/nodejs/forever/file.pid" --uid 'file' -p '/home/nodejs/forever/' -l '/home/nodejs/forever/file.log' -o '/home/nodejs/forever/file.log' -e '/home/nodejs/forever/file.log' -a start /etc/dynamic_ip/nodejs/proxy.js 41789 1.2.3.4:44481 414 file;

где user123 не существует, это всего лишь трюк для выхода из shell после выполнения. script работает, работает forever, я могу закрыть все форварды командой forever stopall от root. Когда я пытаюсь сделать то же самое, что и пользователь http://1.2.3.4/test.php или как www-data, я не могу закрыть его из root или www-data, поэтому даже это не работает.

Я пробовал из Ubuntu 14.04.3 LTS, Ubuntu 14.04 LTS, Debian GNU/Linux 8... еще одно и то же.

Любые идеи?

Спасибо.

4b9b3361

Ответ 1

Если вы запускаете процесс из Apache или веб-сервера, вы уже являетесь пользователем www-data, поэтому сделать sudo su в пользовательском контексте, который у вас уже есть, вероятно, не требуется.

При запуске этой задачи forever вам также может потребоваться закрыть терминалы/входы и напрямую отправить их на задний план. Что-то вроде этого:

// Assemble command
$cmd = '/usr/bin/forever';
$cmd.= ' -d -v --pidfile /tmp/my.pid'; // add other options
$cmd.= ' start';
$cmd.= ' /etc/dynamic_ip/nodejs/proxy.js';
// "magic" to get details
$cmd.= ' 2>&1 1>/tmp/output.log'; // Route STDERR to STDOUT; STDOUT to file
$cmd.= ' &'; // Send whole task to background.
system($cmd);

Теперь здесь не будет выхода, но вы должны иметь что-то в /tmp/output.log, которое могло бы показать, почему forever не удалось, или script разбился.

Если вы запускаете script иногда как root, а затем пытаетесь выполнить ту же команду, что и www-data, вы также можете запускать разрешения для одного или нескольких файлов/каталогов, созданных из исполнения, с правами root, которые теперь конфликтуют при работе в виде www-данных.

Ответ 2

Это часть безопасности PHP, вы говорите, что используете ее с php script и не используете ее из Apache через PHP скрипт.

Веб-скрипты PHP не должны иметь корневой доступ, поскольку они работают под теми же правами, что и пользователь Apache www-data.

Есть способы предотвратить запуск php с правами root, но запустить задачу с правами root, но это немного взломанно, и я не буду делиться этим кодом, но я объясню, чтобы вы могли изучить его. вот где начать

http://php.net/manual/en/function.proc-open.php

С помощью Proccess вы можете выполнить proc. Как и ваш script.js через nodeJS, используя SUDO, а затем прочитайте stdOut и stdErr, подождите для запроса пароля, затем подайте его, написав stdIn для этого процесса.

Не забывайте, что при этом пользователь www-data должен иметь пароль и находиться в списке sudoers