【问题标题】:Starting FOREVER or PM2 as WWW-DATA from a PHP script从 PHP 脚本启动 FOREVER 或 PM2 作为 WWW-DATA
【发布时间】:2016-01-31 19:19:05
【问题描述】:

我有一个名为 script.jsnodejs 脚本。

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 一样正常运行它,但现在我也想包含foreverpm2 功能。当我是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

问题是当我想从带有systemexec 函数的PHP 脚本运行脚本时:

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 script 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 的一个技巧。该脚本有效,运行forever,我可以使用来自root 的命令forever stopall 关闭所有永远。当我尝试运行http://1.2.3.4/test.phpwww-data 用户的相同操作时,我无法从rootwww-data 关闭它,所以即使这样也行不通。

我从Ubuntu 14.04.3 LTSUbuntu 14.04 LTSDebian GNU/Linux 8 尝试过……还是一样。

有什么想法吗?

谢谢。

【问题讨论】:

  • 您无法“看到”永远以另一个用户身份运行的进程,即如果您先使用sudo su www-data,然后再使用forever stopall,它起作用。跨度>
  • 如果我这样做 sudo -u www-data forever stopall 为什么它不起作用?
  • 是的,好问题。我能想到的唯一解释是永远产生子进程,当使用sudo -u 时,只有主进程被尝试关闭,因为该用户和其他进程作为“当前”用户被关闭。
  • 相信我 ii 尝试使用forever2 运行,我必须补充一下,如果我以forever2 登录,我可以在我是这个用户时创建和杀死永远,但这意味着script.sh 计划应该可行,对吧?
  • 我想是的。但如果我理解正确,你不能用www-data 代替forever2 来做.sh 文件技巧?

标签: php linux node.js ubuntu


【解决方案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 失败或脚本崩溃了。

如果您有时以 root 身份运行脚本,然后尝试使用与 www-data 相同的命令,您可能还会遇到一个或多个文件/目录的权限,这些文件/目录是在以 root 身份执行时创建的,现在在运行时会发生冲突作为 www 数据。

【讨论】:

    【解决方案2】:

    这是 PHP 安全性的一部分,您说您是从 php 脚本运行它,而不是通过 php 脚本从 Apache 运行它。

    PHP Web 脚本不应具有 root 访问权限,因为它们在与 Apache 用户 www-data 相同的权限下运行。

    有一些方法可以防止 php 以 root 身份运行,但以 root 身份运行任务,但这有点 hacky,我不打算分享代码,但我会解释一下,以便您查看。从这里开始

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

    通过这样的过程,您可以执行过程。就像你的script.js 通过nodeJS 使用SUDO 然后读取stdOut 和stdErr 等待密码请求然后通过写入stdIn 来提供它。

    不要忘记用户 www-data 必须有密码并且在 sudoers 列表中

    根据 OP 评论 由于 SUDO 的工作方式,PATH 似乎不包含节点可执行文件npm, node 的路径,因此您最好构建一个 .sh(bash 脚本)并使用 sudo 运行它。

    你仍然需要监控这个过程,因为它仍然会要求输入密码

    #!/bin/bash
    sudo -u ec2-user -i
    # change this to the path you want to run from
    cd ~
    /usr/local/bin/pm2 -v 
    

    【讨论】:

    • 相信我,我尝试了一切......现在我正在创建一个不会使用www-data 用户的socket server,只是为了这个问题,想象一下这有多难看......
    • 我通常选择使用 java 来处理这种事情 php 并不是为了管理任何持久性的东西而设计的
    • 我成功地让“apache 用户”获得了节点版本: sudo -u ec2-user /usr/local/bin/node -v 但就是这样,我无法对 pm2 做同样的事情 sudo -u ec2-user /usr/local/bin/pm2 -v 得到这个:/usr/bin/env: node: No such file or directory
    • 这是因为 pm2 应用程序正在寻找节点应用程序并且找不到节点,因为 PATH 变量不会像您那样设置sudo -u 您必须将其作为命令链进行EG 构建一个 bash 脚本并使用 sudo 运行它。我将在中添加对此答案的更新
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-05
    • 1970-01-01
    • 2022-07-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多