Node.js: 在端口80上连接被拒绝

7
我使用Node.js编写了一个Web服务器。 当我尝试使用我为其编写的测试器来测试我的服务器时,只有在我使用的端口不是80时才成功。 我在netstat上进行了检查,没有其他应用程序在使用端口80。 控制台上显示的错误信息是:
Error: connect ECONNREFUSED
  at errnoException (net.js:640:11)
  at Object.afterConnect [as oncomplete] (net.js:631:18)

这种情况下可以做些什么?

服务器使用的端口号是多少?也许您没有权限绑定到80端口。 - Finslicer
1
我已经尝试了8080,它完美地工作了。 - limlim
如果你使用的是Ubuntu(或其他Unix系统),你可以尝试sudo node sample.js。通常这样就可以解决问题了。 - alessioalex
我遇到了类似的问题,但更高的端口分配也不起作用,'sudo'也不行。 - EhevuTov
5个回答

18

不要习惯以特权用户身份运行node。 这是我在6台不同机器上使用的方法:

使用 iptables 将端口80的传入流量转发到8080,如下所示:

sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080

那么请确保保存该内容。
sudo iptables-save

您还需要将这些设置添加到rc.local中,以便在重新启动或实例启动时(在EC2或其他云中的情况下)进行设置。

然后,您可以安全地以任何用户身份开始监听8080节点。


您是否还需要将出站流量转发到端口8080以转发到端口80? - Tom
@Tom 你不需要这样做,那是自动的。 - talentedmrjones
非常赞同这个解决方案。我曾考虑使用Apache虚拟主机来完成相同的事情,但这个方法很有效! - benipsen
@talentedmrjones,如果不进行出站流量的设置,它对我来说是无法工作的。我的Ubuntu版本是12.10。只有在我执行了以下命令后,它才能正常工作。iptables -t nat -A OUTPUT -d localhost -p tcp --dport 80 -j REDIRECT --to-ports 8080 - vumaasha

10

这基本上是对maerics答案的补充,但由于我想添加一个代码示例,所以我写了另一个回答,提供了有关如何防止安全问题的附加信息。

通常,Web服务器会以root身份启动,因为这是在端口号低于1024时所需的,但随后它们会将运行用户更改为非特权用户。

您可以使用process.setuid("username")在node.js中实现此操作。

以下示例启动服务器,然后在作为根用户绑定到端口80后,放弃根权限并切换到用户“www-data”:

function StartServer() {
  console.log("Starting server...");
  // Initalizations such as reading the config file, etc.
  server = http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello World\n');
  });
  try {
    server.listen(80, "0.0.0.0", function(){
      process.setuid("www-data");
    });
  }
  catch(err) {
    console.error("Error: [%s] Call: [%s]", err.message, err.syscall);
    process.exit(1);
  }
}

1
另外,只是提供信息,您可以添加语言语法突出提示链接)到您的代码片段中,使它们更漂亮! - maerics
谢谢,猜想没有在问题中加入Javascript标签就无法自己工作 :) - Bastian
是的,自动检测似乎在某些原因下对 ECMAScript 派生语言有最大的困扰。 - maerics
.setuid 就是我们需要的,特别是在尝试从 Upstart 或类似环境启动时,其他人都会说“使用 -u www-data”。 - Jon J

3
作为普通用户(例如非root用户),您可能没有权限绑定到低于1024(包括80)的端口,请尝试更高编号的端口(1024以上,例如8080)。
【编辑】
根据您的目标系统,并且假设您是其管理员,则可以通过以下方式解决问题:
1. 使用“sudo”执行您的程序,例如:sudo node ./myprogram.js。 2. 或者,在您的系统上登录为“root”用户并正常运行程序。
但是,不要经常这样做(直到您了解原因),它们可能会引入安全漏洞,可能会被恶意、有动机的个人利用。

我必须将端口设置为80(这是我必须提交的作业,因此它还必须在端口80上工作)。我该如何获得此权限? - limlim
系统管理员可以授予权限。请注意,只要运行程序的用户有权限绑定到该端口,您的程序将在任何端口号上都能正常工作。 - maerics
这是我的电脑。我该怎么做? - limlim
@limlim:这取决于你的系统,但尝试使用 sudo node ./myprogram.js 命令,并在提示时输入密码。或者,以 root 用户身份登录并运行程序(但不要养成这个习惯,这是非常糟糕的!)。 - maerics
我添加了一个答案,其中包含一个代码示例,说明如何在服务器启动后放弃root权限,以防止通过作为root响应Web请求而产生安全漏洞。 - Bastian
你也可以在8080上进行监听,并使用iptables将传入的80端口转发到8080,像这样:sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080 && sudo iptables-save - talentedmrjones

0

我在Node.js(任何端口>1024)前使用Nginx服务器(端口80),效果非常好。


0
一个在上面列表中没有看到的备选方案是允许您的进程绑定到特权端口(<1024),方法是执行以下命令来启动节点可执行文件。(请适当调整路径)
setcap 'cap_net_bind_service=+ep' /opt/meteor/.meteor/tools/latest/bin/node

令人烦恼的是,每次更新或更改节点可执行文件时,您都必须重新发出此命令。

敬礼,


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接