从PHP脚本中以WWW-DATA形式启动FOREVER或PM2
我有一个名为从PHP脚本中以WWW-DATA形式启动FOREVER或PM2,php,linux,node.js,ubuntu,Php,Linux,Node.js,Ubuntu,我有一个名为script.js的nodejs脚本 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
script.js的nodejs
脚本
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
一样正常运行它,但现在我想包括永久
或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
问题是,当我想使用系统
或exec
函数从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
命令关闭所有forever。当我尝试运行http://1.2.3.4/test.php
或作为www-data
用户,我无法从root
或www-data
关闭它,因此即使这样也不起作用
我从ubuntu14.04.3lts
,ubuntu14.04lts
,Debian GNU/Linux 8
。。。还是一样
有什么想法吗
谢谢。如果您是从Apache或web服务器中启动此过程,那么您已经是www-data
用户,因此可能没有必要对您已有的用户上下文执行sudo-su
当您启动此永久
任务时,您可能还需要关闭终端/输入并直接发送到后台。大概是这样的:
// 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
中有一些内容,它可以显示永远
失败或脚本崩溃的原因
如果您有时以root用户身份运行脚本,然后尝试使用与www数据相同的命令,您可能也会在一个或多个文件/目录上运行权限,这些文件/目录是以根用户身份执行创建的,现在作为www数据运行时会发生冲突。这是PHP安全的一部分,您说您是从PHP脚本运行它,而不是通过PHP脚本从Apache运行它
PHP web脚本不应具有root访问权限,因为它们在与Apache用户www-data
相同的权限下运行
有一些方法可以防止php以root身份运行,但可以以root身份运行任务,但这有点麻烦,我不打算分享代码,但我会解释,以便您可以研究它。从这里开始
使用这样的过程,您可以执行一个过程。像您的script.js
一样,使用SUDO通过nodeJS,然后读取stdOut和stdErr,等待密码请求,然后通过向stdIn写入密码请求来提供密码
不要忘记,在执行此操作时,用户www data
必须拥有密码,并且必须在sudoers列表中
根据老年退休金计划的意见
由于SUDO的工作方式,路径似乎不包含节点可执行文件的路径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
你不能“看到”永远以另一个用户的身份运行的进程,也就是说,如果你想sudo su www-data
,然后做forever stopall
,它就会工作。如果我做sudo-u www-data-forever stopall
,为什么它不工作?是的,好问题。我能想到的唯一解释是,永远产生子进程,当使用sudo-u
时,只有主进程作为该用户被尝试关闭,而其他进程作为“当前”用户被关闭。相信我,我曾尝试使用永远运行2
,我必须添加,如果我以forever2
的身份登录,我可以在我是这个用户的时候创建和杀死forever,但这意味着script.sh
计划应该有效,对吧?我想是的。但是如果我理解正确的话,你就不能用www data
而不是永远做.sh
文件把戏了。相信我,我什么都试过了。。。现在我正在制作一个socket服务器
,它不会使用www数据
用户,就为了这个问题,想象一下这有多难看……我通常选择使用java来处理这类事情php并不是设计用来管理任何持久性的东西我成功地管理了“apache用户”要获取包含以下内容的节点版本:sudo-uec2user/usr/local/bin/node-v,仅此而已,我无法对pm2 sudo-u ec2 user/usr/local/bin/pm2-v执行同样的操作。v获取此信息:/usr/bin/env:node:没有这样的文件或目录这是因为pm2应用程序正在查找节点应用程序,并且找不到节点,因为路径变量不会像您的dosudo-u
那样设置,您必须将其作为一个命令链来执行构建bash脚本并使用sudo运行它。我将在中添加此答案的更新