[denoland/deno]Deno.ListenOptions 主机名默认为 127.0.0.1,而不是 0.0.0.0

2024-07-17 801 views
5
概括:

hostname使用 的方法未提供时Deno.ListenOptions,进程将绑定到127.0.0.1而不是(所有地址)。这将导致与0.0.0.0之外的所有地址的连接失败。localhost127.0.0.1

lib.deno.d.ts#L1416:复制代码

export interface ListenOptions {
  /** The port to listen on. */
  port: number;
  /** A literal IP address or host name that can be resolved to an IP address.
   * If not specified, defaults to `0.0.0.0`. */
  hostname?: string;
}

不确定这是否是一个错误,或者是否因为自上次更新以来的设计变更而需要更改文档。

复制:

尝试使用 3 个不同的主机名连接到下面的两个示例(使用deno run --allow-net):

  1. http://本地主机:3000
  2. http://127.0.0.1:3000
  3. <YOUR_LAN_IP_ADDRESS>:3000(第一个例子中会失败,但第二个例子中不会失败)
使用默认主机名
import {serve} from 'https://deno.land/std/http/mod.ts';

const port = 3000;

const server = serve({port}); // use default hostname
console.log(`Server running on port ${port}`);

for await (const req of server) {
  req.respond({body: 'hello world'});
}
提供明确的主机名0.0.0.0
import {serve} from 'https://deno.land/std/http/mod.ts';

const hostname = '0.0.0.0';
const port = 3000;

const server = serve({hostname, port}); // specify 0.0.0.0 as hostname (all addresses)
console.log(`Server running on port ${port}`);

for await (const req of server) {
  req.respond({body: 'hello world'});
}

回答

8

默认情况下仅绑定到本地主机似乎比全局绑定更好。感觉如果你想向世界敞开心扉,你会想要明确地表达出来。所以我认为目前的行为是可取的。

其他平台做什么?

9

@kitsonk 我同意——对于默认配置来说,偏向安全是一个好主意。

9

我不同意 Kitson 的观点。我认为大多数人都希望默认监听 0.0.0.0。我会接受 PR 来更改它。

3

此外,它只监听 IPv4,我期望它默认监听两种协议。如果两者无关,请见谅。

8

来自 Node 的文档

基于此,Deno.ListenOptions 主机名应该适用于任何一种情况。

我要尝试一下!

6

我一直在考虑这个问题,并粗略地研究了其他框架如何处理这个问题。我想知道我们是否愿意引入一个属性,ipv6Only这样ListenOptions人们就可以明确如何处理主机名。

所以如果你做了这样的事情:

const listener = Deno.listen({ port: 4500, ipv6Only: true });

主机名将遵循 ipv6 即127.0.0.1,如果未指定,则默认为0.0.0.0

有什么想法吗?

5

@shortdiv 是的,我认为 ipv6 标志是有意义的,因为可能不是每个人都会使用它,但如果存在 ipv6,我认为它会绑定到[::1](localhost)或某个 ipv6 地址,例如[xxxx::xxxx:xxxx:xxxx:xxxx],这在代码库中也有不同的处理方式,其中检查了传递给 listen 函数的地址/主机名是否以 开头'['和结尾']'。所以,也必须处理这一点。但截至目前,要回答@1player 的问题,为了使其也绑定在 ipv6 上,您必须将主机名作为 ipv6 地址传入。

8

我个人不喜欢默认为 127.0.0.1 或 0.0.0.0,或者默认为仅 IPv4。

Node 方法更好:

[::]在 POSIX 操作系统上意味着“监听 IPv4 和 IPv6 上的所有接口”,这是 2020 年更好的默认设置,特别是因为“localhost”可能最好解析为 IPv6 地址 [::1] 并且我们希望能够仅使用“localhost”主机名连接到我们的应用程序。

因此,在我看来,我们应该复制 Node 行为,因为 IPv6 是一个现实,并且开箱即用地支持它比让用户在代码中明确启用它要好。

编辑:当给定 IPv6 监听地址时,所有主流操作系统都会监听这两种协议。因此 [::] 或 [::1] 是比任何其他替代方案更好的默认设置,同时仍与 IPv4 向后兼容。

2

@1player 是的,您说的确实有道理。但我希望这种明确绑定到 ipv6 的功能是一种约束设置,考虑到安全性。但默认情况下,如果不使用标志绑定到 ipv6,用户将不知道自己正在这样做。

5

@Impeekay 这不是建议标志的作用。建议标志将禁用 IPv4

@1player 并非所有主流操作系统。例如,如果您指定,Windows 仅在默认情况下侦听 IPv6 ::。对于双栈,您需要明确设置IPV6_V6ONLY = 0。此外,::1不支持双栈。如果您绑定到::1它,则只会是::1,而不会包括127.0.0.1