Javascript Node.js应用程序可以';即使存在';没有其他进程阻塞端口

Javascript Node.js应用程序可以';即使存在';没有其他进程阻塞端口,javascript,linux,node.js,amazon-ec2,debian,Javascript,Linux,Node.js,Amazon Ec2,Debian,我正在AmazonEC2上运行Debian实例,安装了Node.js。如果我运行下面的代码: http = require('http'); http.createServer(function (request, response){ response.writeHead(200, {'Content-Type':'text/plain'}); response.end('Hello World\n'); }).listen(80); console.log("Running ser

我正在AmazonEC2上运行Debian实例,安装了Node.js。如果我运行下面的代码:

http = require('http');

http.createServer(function (request, response){
  response.writeHead(200, {'Content-Type':'text/plain'});
  response.end('Hello World\n');
}).listen(80);
console.log("Running server at port 80");
我得到下面的输出,它告诉我有另一个进程正在侦听端口80:

Running server at port 80

events.js:72
        throw er; // Unhandled 'error' event
              ^
Error: listen EACCES
    at errnoException (net.js:901:11)
    at Server._listen2 (net.js:1020:19)
    at listen (net.js:1061:10)
    at Server.listen (net.js:1127:5)
    at Object.<anonymous> (/home/admin/nodetests/nodetest.js:6:4)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
我得到下面的输出,它告诉我在端口80没有监听内容:

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1667/sshd       
tcp6       0      0 :::22                   :::*                    LISTEN      1667/sshd
我应该注意到,debian将端口80作为入站规则打开,如果这有区别的话


我的问题是:我做错了什么?为什么我不能识别监听端口80的进程?为什么它在Debian中被阻止?我应该采取什么步骤使代码正确运行

错误代码
EACCES
表示您没有在该端口上运行应用程序的适当权限。在Linux系统上,低于1024的任何端口都需要根访问。

您可以使用以下命令将端口80重定向到应用程序的端口(>1024),而不是在端口80上运行


如果应用程序在端口3000上运行,这将起作用。

简短回答:您可以使用以下命令允许节点访问该端口:

setcap'cap\u net\u bind\u service=+ep'/path/to/nodejs

编辑:


请注意,如果运行的是
apache
,则可以在vhost上创建反向代理。如果您的节点在端口
8080
上运行:

<VirtualHost 127.0.0.1:80>
        ServerName myLocalServer

        ProxyPass        /  http://localhost:8080/
        ProxyPassReverse /  http://localhost:8080/
</VirtualHost>
您需要启用相关的apache模块:

sudo a2enmod proxy_html
sudo a2enmod proxy_http
sudo a2enmod proxy_connect
sudo a2enmod proxy_ajp
sudo service apache2 restart

…现在您可以连接到
http://myLocalServer

我遇到了同样的错误,我尝试使用sudo运行我的应用程序,它对我有效

没有sudo

mansi@mansi:~/NodePractice$ node myFirst.js 
events.js:141
      throw er; // Unhandled 'error' event
      ^

Error: listen EACCES 0.0.0.0:80
    at Object.exports._errnoException (util.js:870:11)
    at exports._exceptionWithHostPort (util.js:893:20)
    at Server._listen2 (net.js:1224:19)
    at listen (net.js:1273:10)
    at Server.listen (net.js:1369:5)
    at Object.<anonymous> (/home/mansi/NodePractice/myFirst.js:6:4)
    at Module._compile (module.js:410:26)
    at Object.Module._extensions..js (module.js:417:10)
    at Module.load (module.js:344:32)
    at Function.Module._load (module.js:301:12)

错误代码
EACCES
表示您没有在该端口上运行应用程序的适当权限。 在Linux系统上,任何低于1024的端口都需要根访问权限

使用
sudo
权限运行程序。
在运行程序之前,请运行
sudo su
命令。

对于那些为开发环境寻找快速简便解决方案的人来说,通过ssh进行端口转发是一个不错的选择:

ssh -L 80:localhost:3000 yourusername@localhost -N
这将本地主机上的端口80转发到本地主机上的端口3000

它需要以root运行(特权端口)。要取消它,只需点击终端中的ctrl-c。(您可以添加
-f
标志以使命令在后台运行,但随后需要再次找到它以终止它)

此解决方案要求您有一个本地运行的ssh服务器,但是,如果您在共享网络上,请记住安全问题。您可能希望至少应用某种级别的附加安全性(禁用密码和根登录)


我个人只在本地机器上使用过。我不确定它会如何影响您请求的处理速度如果您在生产环境中运行此功能,可能有人有想法。无论如何,您需要确保该命令始终保持运行,这会带来更多麻烦。对于生产环境,我建议使用。

六氰化物的答案是正确的。但有什么办法可以让这一切顺利进行吗

答案是肯定的

怎么做

您可以使用
反向代理
例如,在端口
80
上运行
nginx反向代理
,并将代理传递到使用它的节点的目标
ip:port

您可以使用
docker container
进行设置,从而使生活更加轻松。这是你可以拉的码头中心


使用
反向代理
还有更多的好处,你可以用谷歌搜索它。

做到了这一点。发现你必须是root用户才能在新的debian安装中运行iptables,否则$PATH不会指向它。我使用的是谷歌云计算,这让我在触摸80端口时遇到了问题。这太棒了。谢谢。这应该是公认的解决方案。以sudo方式运行web服务器是危险的,如果应用程序中存在任何漏洞,攻击者可能会获得root访问权限;此外,如果应用程序要创建任何文件,其他用户将无法访问这些文件,这会使您使用
sudo
的次数更多。不知道为什么,但在Ubuntu 14.04上,这对我不起作用。我现在通过ssh使用端口转发,这同样简单。因此,如果你有使用sudo的授权,sudo node myapp.js就会这样做(只是为初学者加上它)。@AlexMA但是以root用户身份运行服务器是一件不可能的事。但是,如何在端口80上运行node呢?你应该。。。不使用并使用代理?@PatrickEvans我想最好的做法是在不同的端口上运行,然后像这里提到的那样设置一个端口转发规则:这就成功了@LinuxMint-sudo setcap'cap\u net\u bind\u service=+ep'/usr/local/bin/nodeSometimes更新将更改节点的位置路径,这将停止工作。因此,您需要为节点的新路径再次运行它。看起来,在节点版本8之后,此操作将不再有效。请参阅六氰化物答案下的帖子评论。谢谢这正是你不想做的。它造成了安全问题。
sudo a2enmod proxy_html
sudo a2enmod proxy_http
sudo a2enmod proxy_connect
sudo a2enmod proxy_ajp
sudo service apache2 restart
mansi@mansi:~/NodePractice$ node myFirst.js 
events.js:141
      throw er; // Unhandled 'error' event
      ^

Error: listen EACCES 0.0.0.0:80
    at Object.exports._errnoException (util.js:870:11)
    at exports._exceptionWithHostPort (util.js:893:20)
    at Server._listen2 (net.js:1224:19)
    at listen (net.js:1273:10)
    at Server.listen (net.js:1369:5)
    at Object.<anonymous> (/home/mansi/NodePractice/myFirst.js:6:4)
    at Module._compile (module.js:410:26)
    at Object.Module._extensions..js (module.js:417:10)
    at Module.load (module.js:344:32)
    at Function.Module._load (module.js:301:12)
mansi@mansi:~/NodePractice$ sudo node myFirst.js 
^C
ssh -L 80:localhost:3000 yourusername@localhost -N