Не удается запустить узел с веб-сервера

4

Я пытался запустить npm с веб-страницы PHP, но он никогда не запустится. Я всегда получал код выхода 127 и не выводил. После некоторого тестирования я сузил проблему до shebang в npm, который выглядит следующим образом:

#!/usr/bin/env node

Довольно стандартный, но я сделал несколько тестовых кодов:

<?php
$result = exec("/usr/bin/env node --version", $output, $exit);
var_dump($result);
var_dump($exit);
$result = exec("node --version", $output, $exit);
var_dump($result);
var_dump($exit);
$result = exec("/usr/bin/env gzip --version", $output, $exit);
var_dump($result);
var_dump($exit);

И получил этот вывод в моем браузере:

string(0) ""
int(127)
string(6) "v8.4.0"
int(0)
string(28) "Written by Jean-loup Gailly."
int(0)

Я включил catch_workers_output в конфигурацию PHP-FPM и увидел это в журнале PHP:

[18-Aug-2017 15:15:35] WARNING: [pool web] child 27872 said into stderr: "/usr/bin/env: "
[18-Aug-2017 15:15:35] WARNING: [pool web] child 27872 said into stderr: "node"
[18-Aug-2017 15:15:35] WARNING: [pool web] child 27872 said into stderr: ": No such file or directory"
[18-Aug-2017 15:15:35] WARNING: [pool web] child 27872 said into stderr: ""

Я также попытался запустить exec("which node") с веб-сервера и увидел это в журнале PHP:

[18-Aug-2017 15:31:12] WARNING: [pool web] child 27873 said into stderr: "which: no node in ((null))"

Я попытался запустить var_dump(exec('echo $PATH')) и получил этот вывод:

string(28) "/usr/local/bin:/bin:/usr/bin"

Это похоже на то, как команда env обрабатывает путь. Я попытался установить его вручную, используя директиву fastcgi_param PATH в nginx.conf, но он не изменил вышеописанный вывод.

Выполнение только env и печать вывода выглядит так: без записи PATH:

Array
(
    [0] => USER=nginx
    [1] => PWD=/var/www/html
    [2] => SHLVL=1
    [3] => HOME=/var/cache/nginx
    [4] => _=/bin/env
)

Я нахожусь в дистрибутиве на основе RHEL с отключенным SELinux, запустив PHP-FPM 5.6.31 через сокет UNIX из Nginx 1.12.1. /usr/local/bin/node является символической ссылкой на /usr/local/nodejs/bin/node, которая имеет 775 разрешений. Пользователь nginx владеет каталогом /usr/local/nodejs и всеми его потомками для целей тестирования. Любые предложения?


Обратите внимание, что если я запустил PHP-код из CLI (как пользователь nginx), он работает так, как ожидалось, поэтому это определенно связано с средой CGI/FPM.

$ su -s "/bin/sh" -c "/var/www/html/test.php" nginx
string(6) "v8.4.0"
int(0)
string(6) "v8.4.0"
int(0)
string(28) "Written by Jean-loup Gailly."
int(0)
  • 0
    что происходит, когда вы запускаете exec("which node", $output, $exit); в браузере?
  • 0
    @chiliNUT нет выходных данных и код завершения 1. Что опять же не имеет смысла, потому что я могу запустить его только с node поэтому он должен быть в $PATH . Прекрасно работает в CLI ( $_SERVER["PATH"] возвращает null в FPM, в CLI выглядит нормально)
Показать ещё 3 комментария
Теги:
npm
path

2 ответа

2
Лучший ответ

Вам нужно установить среду PATH в /etc/php5/fpm/pool.d/www.conf, чтобы включить /usr/local/bin/node.

В дистрибутиве ubuntu прокомментировано:

;env[PATH] = /usr/local/bin:/usr/bin:/bin 

так

env[PATH] = /usr/local/bin/node 

должен выполнить эту работу. RHEL не должен сильно отличаться, но даже если строки нет, вы всегда можете добавить его.

Не забудьте перезапустить php-fpm.


Если ничего не работает, вы всегда можете указать путь явно при вызове npm:

exec('PATH=$PATH:/usr/local/bin/node npm');

но это последнее средство, и я бы не рекомендовал его.

  • 0
    Да, похоже, все получилось! Я все еще довольно новичок в FPM и не осознавал, что вы можете установить переменные среды в такой конфигурации.
0

Одна вещь, которая заставляет меня любопытно... Зачем бегать script, поскольку пользователь ngnix работает вообще?

Для реального, ngnix задает php-fpm для процесса, и именно PHP-FPM выполняет ваш script. Таким образом, возможно, PHP-FPM-сервис - это один, который пропускает разрешения для вашего /usr/bin/env node.

Сохраняя все, ngnix нуждается в разрешениях, чтобы поместить свои виртуальные руки в PHP-FPM. Но именно PHP-FPM нуждается в разрешениях для доступа к файлам.

Чтобы упростить решение, вероятно, оно будет исправлено, добавив пользователя PHP-FPM (www-data?) в группу, в которой находится node, а пользователь ngnix уже находится.

Или лучше следуйте этим рекомендациям: https://serverfault.com/a/52703

Изменить # 1:

Я все равно буду следить за приходами.

/usr/local/bin/node является символической ссылкой на /usr/local/nodejs/bin/ node, которая имеет 775 разрешений. Пользователю nginx принадлежит /usr/local/nodejs

Настройка определенного пользователя в /usr/local tree withoux -x является не стандартным. К тому времени, когда /usr/local должен был быть репозиторием для любого пользователя.

Пожалуйста, запустите этот script в разных обстоятельствах (от CLI, FPM, as ngnix, etx) и проверьте свои права:

<?php

$myuid = getmyuid();
$mygid = getmygid();

// you should change to check /usr/local/nodejs/bin/node
$path = '/usr/local/n/versions/node/7.2.0/bin/node'; 

$patharray = array_filter(explode('/', $path));

$dump = "%s \t %s \t %s%s%s \t %s" . PHP_EOL;

$fileOrFolder = __FILE__;
printf("uid \t gid \t rwx \t file" . PHP_EOL);
printf($dump, $myuid, $mygid, (is_readable($fileOrFolder) ? 'r' : '-'), (is_writable($fileOrFolder) ? 'w' : '-'), (is_executable($fileOrFolder) ? 'x' : '-'), $fileOrFolder);

$fileOrFolder = '';
while(count($patharray) > 0) {
    $fileOrFolder .= ('/' .  array_shift($patharray));

    $myuid = posix_getpwuid(fileowner($fileOrFolder));
    $mygid = posix_getgrgid(filegroup($fileOrFolder));

    printf($dump, $myuid['name'], $mygid['name'], (is_readable($fileOrFolder) ? 'r' : '-'), (is_writable($fileOrFolder) ? 'w' : '-'), (is_executable($fileOrFolder) ? 'x' : '-'), $fileOrFolder);

    if (is_dir($fileOrFolder) && !is_executable($fileOrFolder)) {
        echo PHP_EOL . "Ouh, cant go further cause of privelages" . PHP_EOL;
        break;
    }
}

Mine output proofs, что, несмотря на то, что он отличается от другого, PHP может полностью перейти к целевому файлу:

@riddick:~/temp$ php phpowner.php
uid      gid     rwx     file
1000     1000    rw-     /home/yergo/temp/phpowner.php
root     root    r-x     /usr
root     root    r-x     /usr/local
root     root    r-x     /usr/local/n
root     root    r-x     /usr/local/n/versions
root     root    r-x     /usr/local/n/versions/node
root     root    r-x     /usr/local/n/versions/node/7.2.0
                 r-x     /usr/local/n/versions/node/7.2.0/bin
                 r-x     /usr/local/n/versions/node/7.2.0/bin/node
  • 0
    PHP-FPM настроен для работы от имени пользователя / группы nginx
  • 0
    Пожалуйста, обратитесь к моему дополнению. ИМО это все еще случай несоответствия некоторых привилегий.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню