在大多数端口上侦听时,Node.js EACCES错误


249

我正在测试一个应用程序(希望可以在heroku上运行,但是在本地也有问题)。它在运行http.Server.listen()时给我一个EACCES错误-但它仅在某些端口上发生。

因此,我正在本地运行:

joe@joebuntu:~$ node
> var h = require('http').createServer();
> h.listen(900);
Error: EACCES, Permission denied
    at Server._doListen (net.js:1062:5)
    at net.js:1033:14
    at Object.lookup (dns.js:132:45)
    at Server.listen (net.js:1027:20)
    at [object Context]:1:3
    at Interface.<anonymous> (repl.js:150:22)
    at Interface.emit (events.js:42:17)
    at Interface._onLine (readline.js:132:10)
    at Interface._line (readline.js:387:8)
    at Interface._ttyWrite (readline.js:564:14)

我在900端口(或我尝试过的其他20个端口中的任何一个)上没有任何运行,因此这应该可以工作。奇怪的是它确实在某些端口工作。例如,端口3000可以正常工作。

是什么原因造成的?

更新1:

我发现在我的本地计算机上,EACCES错误即将来临,因为我必须以root用户身份运行节点才能绑定到这些特定端口。我不知道为什么会这样,但是使用sudo可以解决。但是,这并不能解释我将如何在Heroku上修复它。在Heroku上无法以root用户身份运行,那么如何在80端口监听?


23
小于1024的端口通常需要提升的权限。在Heroku上,您不监听端口80,而是监听它们通过环境变量告诉您​​的端口,并让它们的路由层处理边缘上的端口80绑定。
马特·弗里曼

您的更新1帮助了我。“ sudo节点myporgram.js”使其运行。
Sabre

Answers:


351

在您的工作站上运行

通常,没有root特权运行的进程不能绑定到低于1024的端口。

因此,请尝试使用更高的端口,或者通过来以更高的特权运行sudo。使用process.setgid和绑定到低端端口后,可以降级特权process.setuid

在heroku上运行

在heroku上运行应用程序时,必须使用PORT环境变量中指定的端口。

参见http://devcenter.heroku.com/articles/node-js

const server = require('http').createServer();
const port = process.env.PORT || 3000;

server.listen(port, () => console.log(`Listening on ${port}`));

3
这是否意味着我必须使用Heroku提供的端口,然后他们会在后台做一些魔术操作以将其传输到80端口?如果我不想在端口80上运行某些东西怎么办?
jwegner

12
是。您只能听我们在$ PORT上告诉您的端口,我们会将80或443路由到您的端口。当我们移动您的测功机时,实际端口始终会变化。在这个时间点上,我们只支持80和443公开路由
威尔

@会否解除限制?具体来说,是否可以侦听80或443以外的端口?考虑到所有因素,这是一个非常严格的设置。
ghayes 2012年

2
为什么要让您的应用程序在不同于http和https的端口上运行?
2012年

1
@Will我想在Heroku上托管一个简单的游戏服务器。Unity需要crossdomain.xml通过843端口进行传输。
polkovnikov.ph 2014年

178

非特权用户(非root用户)无法在1024以下的端口上打开侦听套接字。


5
赞成-这是一个很好的通用规则,但是也有例外,例如Linux上的“功能”。
mikemaccana 2012年

3
您刚刚节省了我几个小时的调试时间。我对此一无所知。
Malharhak

6
我不喜欢这样,我不想在sudo使用节点运行快递服务器时(实际上是Gulp)。所以没有道理
2015年

这种智慧
毛里斯

4
@blamb然后使用MeetMehta的解决方案 ; ^)
ruffin

107

检查此参考链接

授予安全用户使用端口80的权限

请记住,我们不希望以root用户身份运行您的应用程序,但是有一个障碍:您的安全用户没有使用默认HTTP端口(80)的权限。您的目标是通过导航到易于使用的网址(例如, http://ip:port/

不幸的是,除非您以root用户身份登录,否则通常必须使用类似http://ip:port- 的URL ,其中端口号> 1024。

很多人被困在这里,但是解决方案很容易。有几种选择,但这是我喜欢的选择。键入以下命令:

sudo apt-get install libcap2-bin
sudo setcap cap_net_bind_service=+ep `readlink -f \`which node\``

现在,当您告诉Node应用程序您希望它在端口80上运行时,它不会抱怨。


5
这绝对是最好的解决方案。
Mark Lagendijk 2015年

1
@MarkLagendijk:谢谢马克。我也错误地问了同样的问题,并在此处stackoverflow.com/questions/23281895/…上发布了详细的答案。也可以自由编辑它。
2015年

6
为什么这不是答案👍–
KhaledMohamedP

@KhaledMohamedP:很高兴提供了帮助:)
遇到Mehta

谁说这仍然不适用于pm2模块。使用杀死您的pm2 pm2 kill并重新创建它。
Prasanth Jaya

10

另一种方法是进行端口重定向:

sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 900 -j REDIRECT --to-port 3000

并在> 1024端口上运行服务器:

require('http').createServer().listen(3000);

ps顺便说一句,可以对https(443)端口执行相同的操作。


1
谢谢谢谢!这节省了我一个小时的安全端口调试时间,另一个小时的SSL重定向调试时间,还使我能够限制AWS Lightstail上开发服务器的可见性(这不允许按IP地址微调请求)。
miguelmorin

3

这意味着节点无法在定义的端口上侦听。将其更改为1234或2000或3000,然后重新启动服务器。


3

我的天啊!!在我的情况下,我没有这样做,....listen(ip, port)而是...listen(port, ip)抛出了错误消息:Error: listen EACCES localhost

我使用的端口号> = 3000,甚至尝试使用管理员访问权限。什么都没解决。然后仔细观察,我注意到了这个问题。更改为...listen(port, ip),一切开始正常!

只是大声说出来,以防它对其他人有用...


谢谢!我有同样的问题。我已经习惯了使用主机名,端口的所有其他API。
大卫

当我尝试运行Wekan docker image时遇到了这个问题。我解决了使用此技巧。谢谢。
安杰洛Polotto

@ dilip-muthukurussimana您打算....listen(ip, port)在答案中加上四个.)吗?我花了一分钟时间才意识到,您因此而在谈论论据的顺序。
bschlueter

是的,我的意思只是论据的顺序。请不要把....(四个点)放在那,我认为这很明显。
Dilip Muthukurussimana

2

我在Mac上收到此错误,因为默认情况下,它使用与节点服务器使用的端口相同的端口来运行apache服务器,在我的情况下,端口是端口80。我要做的就是用 sudo apachectl stop

希望这对某人有帮助。


2

我的Mac上也出现了此错误。我使用npm run dev运行在Windows中我的应用程序的NodeJS和它工作正常。但是我的mac-上出现了此错误error given was: Error: bind EACCES null:80

解决此问题的一种方法是使用root用户访问权限运行它。您可能会使用sudo npm run dev并且需要输入密码。

通常最好在非特权端口(例如3000)上为您的应用程序提供服务,该端口无需root权限即可工作。

参考:在HTTP 80端口上侦听时,Node.js EACCES错误(权限被拒绝)


2

我有一个类似的问题,这是否认在端口8080上运行,而且任何其他。

原来,这是因为env.local它读取的文件在变量名之后包含注释,例如:

PORT=8080 # The port the server runs at

并尝试使用端口“ 8080 # The port the server runs at” 来解释它,该端口显然是无效的端口(-1)。删除注释完全解决了它。

顺便使用Windows 10和Git Bash。


我知道这不正是这里所描述的问题,但它可能会帮助一个人在那里。我找到了这个问题,寻找问题的答案,所以……也许?


是的,我已经经历过了。.env文件中的值后面的注释可能导致此情况。
达诺斯

1

请记住,如果您使用sudo绑定到端口80,并且正在使用env变量PORT&NODE_ENV,则必须重新导出这些var,因为您现在位于根配置文件而不是用户配置文件下。因此,要使其在Mac上运行,我做了以下工作:

sudo su
export NODE_ENV=production
export PORT=80
docpad run



1

仅通过更改server.js中的端口号即可解决我的错误

const port = process.env.PORT || 8085;

我将端口号从8080更改为8085。

希望能帮助到你。


0

在尝试了许多不同的方法之后,在我的Windows上重新安装IIS解决了该问题。


0

我的错误已使用解决(在Windows上)

app.set('PORT', 4000 || process.env.PORT);

app.listen(app.get('PORT'), <IP4 address> , () => {
    console.log("Server is running at " + app.get('PORT'));
});

允许NodeJS应用访问Windows防火墙中的网络。


0

重新启动还不够!解决问题的唯一方法是通过以下方法:

您必须终止在该端口上运行的服务。

在cmd上,以管理员身份运行,然后键入:netstat -aon | 查找/ i“正在收听”

然后您将获得一个包含活动服务的列表,搜索在4200运行的端口,并使用进程ID(最后一列将其杀死)

:taskkill / F / PID 2652

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.