如何在Node.js server.listen()中使用可选的主机名参数

10

根据我目前在教程中阅读到的内容,server.listen(port[, hostname][, backlog][, callback]) 中可选的 hostname 参数通常是 127.0.0.1(回环地址)、0.0.0.0监听所有可用的网络接口,默认选项)或服务器可用的实际 IP 地址。其他任何值都会导致 Error: listen EADDRNOTAVAIL 错误。这是整个情况吗?(我认为主机名从技术上来说与 IP 不同...)

我无法通过文档找到太多相关信息...

1个回答

19

所以,为了使此功能正常工作,您需要一个可解析的DNS主机名。举一个快速的例子,我编辑了/etc/hosts文件,并添加了以下条目:

因此,您需要一个可解析的DNS主机名才能让此功能正常工作。举个例子,我编辑了/etc/hosts文件,加入了以下条目:

...
127.0.0.1 MyTestDnsHostName.local

然后我使用经典的dscacheutil -flushcache刷新了解析器缓存,并在一个简单的Node.js服务器中使用了以下代码片段。

var http = require('http')
  , PORT = 8080;

function handleRequest( request, response ){
    response.end( 'It Works!' );
}

var server = http.createServer( handleRequest );

server.listen( PORT, "MyTestDnsHostName.local", 34, function(){
    console.log( "Server listening on port:%s", PORT );
});

确实有效。

错误EADDRNOTAVAIL表示它是可解析的但不可用;现在,为了能够绑定到它,它也应该可绑定(可用)。

您可以执行lsof -i TCP来检查它绑定在哪里。

然而,我不明白为什么您要将服务器绑定到其他地方;绑定到环回是最佳实践。


是的,这实际上是一个安全漏洞;如果将其绑定到所有可用接口0.0.0.0,那么您实际上要说的是侦听每个可用的网络接口。这可能会导致安全漏洞,因为它可能会绑定到您不想要的适配器;我在部署RoR应用程序时亲身经历过这种情况。

0.0.0.0/0子网是一种非常高级的方式,可以说:这些都是我在这台计算机上拥有的所有网络接口,而127.0.0.1始终是本地专用接口。如果绑定到此,您就可以摆脱许多安全问题,其中一个问题是“黑客”试图在所有接口上附加侦听器,如果您没有非常严格的防火墙,则可能存在泄漏。

这不是一个规则,而只是一个最佳实践。

P.S.:代码是我从Modulus博客中提取的片段;如果我想尝试一些东西,它很快速。


你能提供“绑定到回环是最佳实践”的支持吗?我认为默认的全捕获0.0.0.0是正确的选择... 我很好奇何时/为什么要在其他地方绑定服务器,因此问了这个问题 :) - Yibo Yang
我不确定绑定到回环除了在开发中是否有效,但你应该想要指定你想要绑定的接口。据我所知,可选的第二个参数实际上是主机而不是主机名。你可以提供一个主机名,服务器将尝试查找与该地址关联的IP,或者你可以指定地址。你还可以指定一个Unix套接字(它有一个文件路径)。 - Chanoch
1
现代绑定到特定地址的一个原因是使用容器。容器可能加入多个网络 - 管理和容器间通信。您可能希望确保特定的 API 服务器仅绑定到它将接受通信的网络上,作为安全的另一层,以及 TLS、客户端证书/令牌和基于 IP 的白名单。 - Chanoch
最后一点,文档不是很有帮助,但维基百科的链接提供了关于0.0.0.0/:::如何工作的一些有用信息,这可以为weirdpanda的答案添加一些信息。 - Chanoch

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