hrishikeshk
(Hrishikesh Kokate)
2023 年11 月 18 日 10:22
1
跟进:API connection via ipv6 vs. ipv4 - support - Discourse Meta
我最近将 Node.js 从 18 升级到 20,我的应用程序突然无法从 Discourse 获得 API 响应。花了我一些时间才弄清楚这与上述问题有关。我通过仅使用 IPv4 进行连接进行了验证,例如:
import {Agent} from 'node:https'
import axios from 'axios'
import {env} from 'node:process'
export const axiosDiscourse = axios.create({
baseURL: 'https://<discourse-url>',
headers: {
'api-key': env['DISCOURSE_KEY'],
'api-username': env['DISCOURSE_USERNAME']
},
httpsAgent: new Agent({
family: 4
})
})
重要的是指定 HTTP Agent——我之前没有使用它。现在可以工作了,但我正试图摆脱 Axios,这样我就可以使用其他基于 fetch 的库,如 Wretch(主要是为了通过在前端也使用它来减小包大小):[elbywan/wretch: A tiny wrapper built around fetch with an intuitive syntax. (github.com )](https://github.com/elbywan/wretch)。然而,fetch 没有指定 IPv4 或 IPv6 的选项。因此,我认为我需要:
强制仅使用 IPv4,尽管我迄今为止的所有尝试都未能成功。
与 Discourse 确认如何才能在 IPv6 上实现此功能。
我的应用程序正在连接到各种其他 API,没有一个出现此问题,只有与 Discourse 的连接失败了。
以防万一,这是我收到的错误:
Error: connect ETIMEDOUT 184.105.99.43:443
at createConnectionError (node:net:1634:14)
at Timeout.internalConnectMultipleTimeout (node:net:1685:38)
at listOnTimeout (node:internal/timers:575:11)
at processTimers (node:internal/timers:514:7) {
errno: -110,
code: 'ETIMEDOUT',
syscall: 'connect',
address: '184.105.99.43',
port: 443
},
Error: connect ENETUNREACH 2602:fd3f:3:ff01::2b:443 - Local (:::0)
at internalConnectMultiple (node:net:1176:40)
at Timeout.internalConnectMultipleTimeout (node:net:1687:3)
at listOnTimeout (node:internal/timers:575:11)
at processTimers (node:internal/timers:514:7) {
errno: -101,
code: 'ENETUNREACH',
syscall: 'connect',
address: '2602:fd3f:3:ff01::2b',
port: 443
}
有趣的是,与上面提到的帖子不同,我没有得到长时间的响应。我的请求立即因这个错误而失败。API 调用在浏览器、curl 和我可以测试的任何其他工具中都可以正常工作。
我向 API 发出请求的方式并不重要,只要我从我的应用程序发出请求即可。它就是会失败,并且只有在使用上面提到的 family 选项时才能工作。在链接的帖子中,我看到有人提到:
你需要调查为什么你的网络上的 IPv6 连接不起作用。
我对这两点有疑虑:
我不知道如何具体检查这一点。
不确定为什么这只会是 Discourse 的问题,而且只在我的应用程序中出现。
1 个赞
hrishikeshk
(Hrishikesh Kokate)
2023 年11 月 18 日 10:30
2
另外需要注意的是,这仅在我的WSL实例内部发生。如果我在宿主Windows设备上直接运行我的应用程序,它可以正常连接。
我知道这可能是我设置中的一个非常具体的问题,但我现在不知道该从哪里入手查找问题。任何提示都会有帮助!
1 个赞
您使用的库似乎同时尝试通过 IPv4 和 IPv6 进行连接;这是个好消息,意味着您没有遇到与此处 相同的问题!
让我们分别处理它们:
这意味着您这边设置了一个 TCP SYN 来尝试连接到托管实例,但没有收到响应。这通常意味着以下情况之一:
请求未到达服务器
服务器(或路径上的某个设备)故意静默丢弃了它
响应未返回到您的机器
由于
这很可能是您机器上网络设置的问题。
这意味着您的网络堆栈说“我无法到达那里”,这是没问题 的,因为您显然会回退到 IPv4。
总而言之,我怀疑:
从您的机器连接 IPv4 失败(尚不清楚这是否属实,请验证——“可以正常连接”可能意味着它正在使用 IPv4 或 IPv6)
从您的 WSL 容器连接 IPv4 失败
从您的机器连接 IPv6 正常
从您的 WSL 容器连接 IPv6 失败
请向 @team 发送一条消息,告知您的外部 IPv4 地址,我们将检查它是否被故意丢弃——我们确实屏蔽了一些行为不端的 IP 范围,这将有助于我们排除这种情况。
但是,如果 IPv4 和 IPv6 都从您的机器连接正常,但从您的 WSL 容器连接失败,那么您需要解决 WSL 设置方面的问题。
hrishikeshk
(Hrishikesh Kokate)
2023 年11 月 20 日 10:00
4
非常感谢您的回复。
关于您的嫌疑,这是我到目前为止可以测试的内容:
根据我的理解,这应该只允许 IPv4 连接。如果可以,那就可以了。
curl -4 https://<host>/latest.json?order=created
从 WSL 运行,它运行正常(我收到了响应)。
curl -6 https://<host>/latest.json?order=created -v
* Trying 2602:fd3f:3:ff01::2b:443...
* Immediate connect fail for 2602:fd3f:3:ff01::2b: Network is unreachable
* Closing connection 0
curl: (7) Couldn't connect to server
从 WSL 运行,它立即失败了。
今天我在 WSL 上遇到了一些麻烦,所以我最终重新配置了一个全新的安装。这是一个全新的实例,只安装了 asdf 和 Node.js(并更新了所有系统软件包)。不确定这是否仍然与 WSL 端的一些错误配置有关——我现在应该使用所有默认设置。
我将我的公共 IPv4 地址分享给提到的组。
hrishikeshk
(Hrishikesh Kokate)
2023 年11 月 20 日 10:02
5
嗯,我还没看到发送私人消息的方法,可能是因为我是新用户。
hrishikeshk
(Hrishikesh Kokate)
2023 年11 月 20 日 10:07
6
更有趣的是……当我检查我的公共 IPv4 地址时,该网站还试图向我显示我的 IPv6 地址,并显示“未检测到 IPv6”。因此,我继续检查我是否根本没有 IPv6 连接,然后我找到了这个页面:如何在 TP-Link 无线路由器上设置 IPv6 服务
它显示路由器应该有一个专门的部分来使用 IPv6。我的路由器没有这个部分,而且我也找不到那里显示的 PPPoE v6 选项。所以也许我的路由器根本不支持 IPv6——这可能就是为什么 IPv6 连接失败的原因(也解释了为什么当我禁用 Windows 设置中的 IPv4 时,我基本上失去了互联网连接)。
编辑:我有这个路由器 TL-WR841N | 300Mbps 无线 N 路由器 | TP-Link 印度 ,它说支持 IPv6
编辑 2:但是使用类似 v6.testmyipv6.com 的东西会给我 ERR_NAME_NOT_RESOLVED,所以看起来 IPv6 确实对我不起作用。
如果这是问题所在,我仍然不知道为什么会突然开始发生这种情况。它已经正常工作了一段时间。
我已经给你稍微推了一下。 如果你现在点击 @team ,你应该就能看到消息按钮了。
1 个赞
hrishikeshk
(Hrishikesh Kokate)
2023 年11 月 20 日 11:26
10
附加数据点,我从使用 IPv6 的移动网络切换到了热点。我现在可以使用以下命令进行验证:
curl -6 https://<host>/latest.json?order=created -v
* Trying 2602:fd3f:3:ff01::2b:443...
* Immediate connect fail for 2602:fd3f:3:ff01::2b: Network is unreachable
* Closing connection 0
curl: (7) Couldn't connect to server
仍然以类似的方式失败。但是,在 Windows 设置中禁用 IPv4 后,我可以访问互联网,这与之前不同。所以新的数据:
Windows 上的 IPv4:工作正常
Windows 上的 IPv6:工作正常
WSL 上的 IPv4:工作正常
WSL 上的 IPv6:失败
如果我不为 curl 指定 -4 或 -6,它会回退到 IPv4(IPv6 立即失败):
curl https://<host>/latest.json?order=created -v
* Trying 184.105.99.43:443...
* Trying 2602:fd3f:3:ff01::2b:443...
* Immediate connect fail for 2602:fd3f:3:ff01::2b: Network is unreachable
* Connected to <host> (184.105.99.43) port 443 (#0)
我还运行了:
ping -6 google.com
从 Windows 和 WSL 运行。它在 Windows 上工作正常,在 WSL 上失败。我认为我现在有足够的信息和验证来证明我的 WSL 实例的 IPv6 连接出现了问题。看起来像是一个问题:无法访问仅 IPv6 地址 · Issue #4518 · microsoft/WSL (github.com)
hrishikeshk
(Hrishikesh Kokate)
2023 年11 月 20 日 11:37
11
终于!
根据上面链接的讨论,我能够在 .wslconfig 中添加
[experimental]
networkingMode=mirrored
这样我的 WSL 实例就获得了 IPv6 连接。我现在可以成功运行:
curl -6 https://<host>/latest.json?order=created
不过在我的 WiFi 上仍然无法工作,这很可能是因为这个旧路由器不支持 IPv6。在使用我手机的热点时,它可以正常工作。
非常感谢 @JammyDodger 的指导,你指明了正确的方向!
Hrishikesh Kokate:
WSL 上的 IPv4:有效
好的,看来在原始帖子和现在之间肯定发生了一些变化,因为您之前收到的是:
很高兴看到现在它能正常工作了。
hrishikeshk
(Hrishikesh Kokate)
2023 年11 月 20 日 16:42
13
是的,这仍然让我感到困惑。正如我之前提到的,我之前能够通过 WSL 发送 curl 请求并且可以正常工作。不知何故,在我的应用程序中使用 Axios 却失败了(也许是 Axios 或 Node.js 的问题?)。
不知何故,curl -4 仍然有效,并且在我指定 httpFamily 时 Axios 也有效,正如我在原始帖子中所示。但这并不是一个我会再为之烦恼的错误。
hrishikeshk
(Hrishikesh Kokate)
2023 年11 月 20 日 17:13
14
为了进行健全性检查,我回滚到了 Node.js 18,并且无需指定 httpFamily 即可连接,因此这肯定是在 Node.js 19 或 20 中发生了一些变化。但正因为如此,我至少了解了 IPv6 的问题,否则我仍然不会去搜索或了解它。
我也可以使用 bun 而不是 Node.js 来运行代码,而无需指定 IPv4 问题。我已经联系了 Node.js:https://github.com/orgs/nodejs/discussions/50826