强制使用http2连接,解决Cloudflare Tunnels无法建立隧道连接的问题

最近使用Cloudflare Tunnels发现总是无法与Cloudflare建立隧道连接

日志,赫然看到下面的报错:

2023-10-13T09:52:58Z ERR Failed to create new quic connection error="failed to dial to edge with quic: timeout: no recent network activity" connIndex=1 ip=198.41.192.227
2023-10-13T09:52:58Z INF Retrying connection in up to 2s seconds connIndex=1 ip=198.41.192.227
2023-10-13T09:52:58Z ERR Connection terminated error="failed to dial to edge with quic: timeout: no recent network activity" connIndex=1
注意其中的关键一行:ERR Failed to create new quic connection error="failed to dial to edge with quic: timeout: no recent network activity" 。

意思就是:创建新的quic连接失败,使用quic协议无法连接到边缘服务器。简单说就是使用quic协议无法成功建立隧道!

Cloudflare Tunnels无法建立隧道连接的原因:

为什么无法使用quic协议创建隧道呢?这就要从quic协议本身的特性说起了,我直接引用某度百科的原话:

QUIC是快速UDP网络连接(英语:Quick UDP Internet Connections)的缩写,这是一种实验性的传输层网络传输协议,由Google公司开发,在2013年实现。

也就是说,quic不同于目前主流的http协议,它是建立在UDP之上的,而因为众所周知的国情,UDP协议在国内运营商眼里是不好的,是被歧视的,最后的结果就是会阻断基于UDP的连接!是不是豁然开朗?

原因和背后的原因都搞清楚,但在笔者脑海里还有一个问题无法释怀,那就是Cloudflared在多次使用quic协议无法创建隧道后,为何不切换到http协议呢?本着一踹到底的莽劲,笔者还真找到了原由,下面是Cloudflare官方在Github答issues的原话(翻译成中文):

让我重申一下这背后的原因:我们正在“强制”quic协议,因为我们(Cloudflare)认为它是互联网未来的重要组成部分。但是许多网络仍然阻止UDP。我们必须迫使这些网络背后的管理员以某种方式感受到这种“痛苦”,以便人们意识到并开始允许UDP出口。

例如,我们的私有DNS解析使用UDP,仅适用于QUIC协议。因此,用户启动默认为 http2(不支持 UDP 代理)的隧道并且没有私有 DNS 解析工作是令人沮丧的。

好了,谜底出来了,Cloudflare故意在默认参数中设置了quic协议,且不支持自动降级/切换到http2,如果你想用http2可以手工指定,就是这么简单粗暴,为广大用户操碎了心!

解决方法

笔者抽丝剥茧,终于理清了问题的原因和解决方法,那么下面就简单了,只需动动手,在Cloudflared容器的启动参数中将协议改为http2就可以了:

在command中增加--protocol http2 即可,此时强制指定协议为http2,使用的是TCP,这样就不会被运营商阻断了。

当然,也可以设置为--protocol auto ,开启自动切换,默认依然是quic,但是失败后可自动切换到http2。

在debian中,修改:/etc/systemd/system/cloudflared.service

cloudflared --no-autoupdate tunnel run --protocol http2 --token *********

如果是Docker容器:

docker run --restart=always -d cloudflare/cloudflared:latest tunnel --no-autoupdate --protocol http2 run --token **********

然后重新创建和启动容器,查看日志就可以看到,使用http2成功创建了隧道。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注