Linux 即使没有其他进程阻塞端口,Node.js 应用程序也无法在端口 80 上运行

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18947356/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-07 00:54:59  来源:igfitidea点击:

Node.js app can't run on port 80 even though there's no other process blocking the port

javascriptlinuxnode.jsamazon-ec2debian

提问by Brian Yeh

I'm running an instance of Debian on Amazon EC2 with Node.js installed. If I run the code below:

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

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");

I get the output below which tells me there's another process listening 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)

Now when I check to see if there's a process (as root in case anything is hidden) listening on port 80 using:

现在,当我检查是否有一个进程(以 root 身份,以防任何东西被隐藏)侦听端口 80 时使用:

netstat -tupln

I get the below output, which tells me theres nothing listening at port 80:

我得到以下输出,它告诉我在端口 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

I should note that the debian has port 80 open as an inbound rule if that makes a difference.

我应该注意到 debian 将端口 80 作为入站规则打开,如果这有所不同的话。

My question is: What am I doing wrong? How come I can't identify the process listening to port 80? Why is it blocked in Debian? What steps should I take to get the code running correctly?

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

采纳答案by hexacyanide

The error code EACCESmeans you don't have proper permissions to run applications on that port. On Linux systems, any port below 1024 requires root access.

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

回答by Kamrul

Instead of running on port 80 you can redirect port 80 to your application's port (>1024) using

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

iptables -t nat -I PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 3000

This will work if your application is running on port 3000.

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

回答by Reut Sharabani

Short answer: You can allow node access to that port using:

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

setcap 'cap_net_bind_service=+ep' /path/to/nodejs

setcap 'cap_net_bind_service=+ep' /path/to/nodejs

long answer

长答案

Edit:

编辑:

May not work on new node versions

可能不适用于新的节点版本

回答by Redsandro

Note that if you have apacherunning, you can create a reverse proxy on a vhost. If your node is running on port 8080:

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

<VirtualHost 127.0.0.1:80>
        ServerName myLocalServer

        ProxyPass        /  http://localhost:8080/
        ProxyPassReverse /  http://localhost:8080/
</VirtualHost>

Of course, add server to /etc/hosts:

当然,将服务器添加到/etc/hosts

127.0.0.1    myLocalServer

You will need to enable the relevant apache modules:

您需要启用相关的 apache 模块:

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

...and now you can connect to http://myLocalServer.

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

回答by Parth Pachchigar

I have got the same error and I tried running my application using sudo and it worked for me.

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

without 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)

and with sudo

和 sudo

mansi@mansi:~/NodePractice$ sudo node myFirst.js 
^C

回答by akshith ranjan

The error code EACCESmeans you don't have proper permissions to run applications on that port. On Linux systems, any port below 1024 requires root access.

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

Run the program with sudopermision. Run sudo sucommand before running the program.

sudo许可运行程序。运行sudo su运行程序之前命令。

回答by panepeter

For those looking for a quick and easy solution for a development environment, port forwarding via ssh can be a nice alternative:

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

ssh -L 80:localhost:3000 yourusername@localhost -N

This forwards port 80 on localhost to port 3000 on localhost.

这会将本地主机上的端口 80 转发到本地主机上的端口 3000。

It needs to be run as root(privileged port). To cancel it, simply hit ctrl-c in the terminal. (You can add the -fflag to have the command run in the background, but then you need to find it again to kill it).

它需要以root(特权端口)身份运行。要取消它,只需在终端中按 ctrl-c 即可。(您可以添加-f标志以使命令在后台运行,但是您需要再次找到它才能杀死它)。

This solution requires you to have an ssh server running locally. It can be done quickly, but please bear in mind the security implications if you are on a shared network. You might want to apply at least some level of additional security (disable password & root login).

此解决方案要求您在本地运行 ssh 服务器它可以快速完成,但如果您在共享网络上,请记住安全隐患。您可能希望至少应用某种级别的额外安全性(禁用密码和 root 登录)。

I personally only ever use this on my local machine. I'm not sure how it affects the processing speed of your requests if you run this on production, maybe someone has an idea. Anyway, you would need to make sure this command keeps running all the time, which introduces more headaches. For production environments, I suggest using a reverse proxy like nginx.

我个人只在我的本地机器上使用过它。如果您在生产中运行它,我不确定它如何影响您的请求的处理速度,也许有人有想法。无论如何,您需要确保此命令一直运行,这会带来更多麻烦。对于生产环境,我建议使用像 nginx 这样反向代理

回答by webcrawler

Using PORT 80 requires some special permissions. Using sudobefore running statement of the app solved my problem. for example, if you are using npm to run your app, you can type sudo npm start

使用 PORT 80 需要一些特殊权限。sudo在应用程序的运行语句之前使用解决了我的问题。例如,如果您使用 npm 来运行您的应用程序,您可以输入sudo npm start

回答by Ali_Hr

the hexacyanide answer is right. but is there any solution to make this work?

六氰化物的答案是正确的。但是有什么解决方案可以使这项工作?

the answer is yes.

答案是肯定的。

how?

如何?

you can use a reverse proxyfor example run a nginx reverse proxyon port 80and pass the proxy to destination ip:portthat node use it.

您可以使用reverse proxy例如nginx reverse proxy在端口上运行一个80并将代理传递到ip:port该节点使用它的目的地。

you can set this up using docker containerthat makes life even easier. this is the official build of nginxin docker hub that you can pull it.

您可以使用docker container它进行设置,使生活更轻松。这是docker hub中 nginx官方构建,你可以拉它。

there's even more benefits in using reverse proxythat you can google it.

使用还有更多好处reverse proxy,你可以谷歌它。