使用本页面诊断并解决 Cloudflare Tunnel 的常见问题。许多问题可通过升级到最新版本的 cloudflared 来解决 — 在进一步调查之前,请参阅更新 cloudflared。
有关隧道运行状况监控、日志和指标,请参阅监控。
当 cloudflared 无法访问 Cloudflare 网络时,它会记录指示问题是 DNS 解析、QUIC (UDP) 还是 TCP 连接的特定错误消息。
ERR edge discovery: error looking up Cloudflare edge IPs: the DNS query failed
error="lookup _v2-origintunneld._tcp.argotunnel.com on 172.19.64.1:53: no such host"此错误意味着您计算机上配置的 DNS 解析器无法解析 cloudflared 用于发现 Cloudflare Tunnel 目标 IP 的 SRV 记录。常见原因包括剥离或拦截 SRV 记录的企业 DNS 解析器,以及返回压缩 SRV 记录的 DNS 解析器。
诊断方法:
在 cloudflared 主机上,运行:
dig SRV _v2-origintunneld._tcp.argotunnel.com如果收到 SERVFAIL、NXDOMAIN 或空回复,请使用 Cloudflare 的公共解析器进行测试:
dig SRV _v2-origintunneld._tcp.argotunnel.com @1.1.1.1解决方法:
- 如果
1.1.1.1返回结果但您的本地解析器没有,请将主机配置为使用 Cloudflare DNS (1.1.1.1) 或其他公共解析器。 - 如果两个解析器都不返回结果,则可能是防火墙拦截了出站 DNS 查询(UDP 端口
53)。请与您的网络管理员合作允许 DNS 流量。
ERR edge discovery: error looking up Cloudflare edge IPs: the DNS query failed
error="lookup _v2-origintunneld._tcp.argotunnel.com on 127.0.0.11:53:
read udp 127.0.0.1:53467->127.0.0.11:53: i/o timeout"此变体表示来自 cloudflared 的 DNS 查询被拦截或完全丢弃 — 解析器根本没有响应。这在内部 DNS 解析器(127.0.0.11)无法访问或配置错误的容器环境(Docker、Kubernetes)中很常见。
解决方法:
- 在 Docker 中,验证容器的 DNS 配置(
/etc/resolv.conf)。在运行容器时,您可以使用--dns 1.1.1.1覆盖解析器。 - 在 Kubernetes 中,验证
kube-dns或CoreDNS服务是否正在运行并可从 pod 访问。 - 在
cloudflared主机上,验证/etc/resolv.conf中列出的解析器是否可访问并响应查询。
ERR Failed to dial a quic connection error="failed to dial to edge with quic:
timeout: handshake did not complete in time" connIndex=0 ip=198.41.192.227
INF Retrying connection in up to 2s connIndex=0 ip=198.41.192.227此错误意味着 cloudflared 已解析 Cloudflare Tunnel 目标 IP,但无法通过 UDP 端口 7844 完成 QUIC 握手。您的网络或防火墙拦截了发往 Cloudflare 的出站 UDP 流量。
cloudflared 会以指数退避的方式重试(2、4、8、16、32,最高 64 秒)。在耗尽重试次数后,它会回退到基于 TCP 的 HTTP/2:
INF Switching to fallback protocol http2 connIndex=0如果回退也失败,您将看到 TCP 连接超时 错误。
诊断方法:
在 cloudflared 主机上,测试端口 7844 的连接性:
nc -uvz -w 3 198.41.192.227 7844将 198.41.192.227 替换为您错误消息中显示的 IP。如果端口关闭或被防火墙拦截,该命令将返回 Connection refused 或超时。
解决方法:
- 允许出站 UDP 流量通过您的防火墙或安全组到达端口
7844。请参阅完整的 IP 和端口列表。 - 如果无法打开 UDP,
cloudflared会自动回退到基于 TCP 的 HTTP/2。您也可以通过设置--protocol http2运行时参数来强制使用 HTTP/2,但建议使用 QUIC 以获得更好的性能。
ERR Unable to establish connection with Cloudflare edge
error="DialContext error: dial tcp 198.41.200.43:7844: i/o timeout" connIndex=0
ERR Serve tunnel error
error="DialContext error: dial tcp 198.41.200.43:7844: i/o timeout" connIndex=0此错误意味着 cloudflared 无法通过 TCP 端口 7844 访问 Cloudflare。如果它上面还显示QUIC 握手超时,则说明 UDP 和 TCP 均被阻止 — 隧道根本无法连接。
诊断方法:
作为快速测试,运行:
curl -v https://region1.v2.argotunnel.com:7844如果连接挂起,则您的主机和 Cloudflare 之间的流量被丢弃。
要测试 cloudflared 是否可以连接到端口 7844,请运行:
nc -vz -w 3 198.41.200.43 7844将 198.41.200.43 替换为您错误消息中显示的 IP。如果端口关闭或被防火墙阻止,该命令将返回 Connection refused 或超时。
解决方法:
- 允许出站 TCP 流量通过端口
7844到达 Cloudflare Tunnel IP 范围。 - 如果您的环境完全屏蔽了端口
7844(包括 UDP 和 TCP),则隧道将无法运行。请与您的网络管理员协作以允许此端口上的出站流量。
如果在安装远程管理隧道时看到此错误,请确保此机器上没有其他 cloudflared 实例以服务形式运行。任何给定机器上只能有一个 cloudflared 实例以服务形式运行。请改为向您现有的隧道添加额外路由。或者,您可以运行 sudo cloudflared service uninstall 来卸载 cloudflared。
如果无法保存隧道的公共主机名,请选择其他主机名或删除现有 DNS 记录。从 Cloudflare 仪表板 ↗查看您域名的 DNS 记录。
如果在运行隧道时遇到以下错误,请仔细检查您的 config.yml 文件,并确保 credentials-file 指向正确的位置。您可能需要将 /root/ 更改为您的主目录。
cloudflared tunnel run2021-06-04T06:21:16Z INF Starting tunnel tunnelID=928655cc-7f95-43f2-8539-2aba6cf3592d
Tunnel credentials file '/root/.cloudflared/928655cc-7f95-43f2-8539-2aba6cf3592d.json' doesn't exist or is not a file要开始使用 Cloudflare Tunnel,Cloudflare 账户中的超级管理员必须首先通过 cloudflared login 登录。客户端将启动浏览器窗口,提示用户在其 Cloudflare 账户中选择一个主机名。选择后,Cloudflare 会生成一个由三个部分组成的证书:
- 该主机名的源证书公钥
- 该域的源证书私钥
- Cloudflare Tunnel 专用的令牌
这三个部分被捆绑成一个 PEM 文件,在登录流程中只下载一次。主机证书对根域及其下一级子域有效。Cloudflare 使用该证书文件对 cloudflared 进行身份验证,以便在 Cloudflare 中为您的域创建 DNS 记录。
第三部分(令牌)由所选域的区域 ID 和首次使用登录命令进行身份验证的用户的 API 令牌组成。当用户权限发生变化时(例如,该用户从账户中移除或成为另一个账户的管理员),Cloudflare 会滚动该用户的 API 密钥。但是,通过 cloudflared 下载的证书文件保留旧的 API 密钥,可能导致身份验证失败。用户需要再次通过 cloudflared 登录以重新生成证书。或者,管理员可以创建专用的服务用户进行身份验证。
这意味着源站使用了 cloudflared 不信任的证书。例如,如果您的服务器与 Cloudflare 之间的代理中使用了 SSL/TLS 检测,可能会出现此错误。解决方法:
- 将证书添加到系统证书池。
- 使用
--origin-ca-pool标志并指定证书路径。 - 使用
--no-tls-verify标志停止cloudflared检查证书的信任链。
1033 错误表示您的隧道未连接到 Cloudflare 网络,原因是 Cloudflare 网络无法找到健康的 cloudflared 实例来接收流量。
首先,通过转到 Networking(网络) > Tunnels(隧道) 或运行 cloudflared tunnel list,检查您的隧道在 Cloudflare 仪表板 ↗中是否显示为 Active。如果隧道不是 Active 状态,请根据以下隧道状态检查并采取必要措施:
| 状态 | 含义 | 建议的操作 |
|---|---|---|
| Healthy(健康) | 隧道处于活动状态,并通过与 Cloudflare 全球网络的四个连接来提供流量服务。 | 无需采取任何操作。您的隧道运行正常。 |
| Inactive | 隧道已创建(通过 API 或 仪表板),但从未运行 cloudflared 连接器来建立连接。 |
在您的源服务器上安装并运行 cloudflared 以将隧道连接到 Cloudflare。您可以在 Cloudflare 仪表板中的 Networking(网络) > Tunnels(隧道) 下找到安装命令——选择您的隧道,然后选择 Overview(概览) 选项卡中的 Add a replica(添加副本)。对于基于 API 的设置,请参阅安装并运行隧道。 |
| Down(中断) | 隧道此前已连接,但当前已断开连接,因为 cloudflared 进程已停止。 |
1. 确保 cloudflared 服务或进程在您的服务器上处于活动运行状态。 2. 检查服务器端问题,例如机器断电、应用程序崩溃或最近的网络变更。 |
| Degraded(降级) | cloudflared 连接器正在运行且隧道正在提供流量服务,但至少有一个单独的连接失败。若隧道可用性进一步降级,可能会有隧道停机并无法提供流量服务的风险。 |
1. 查看您的 cloudflared 日志以获取连接失败或错误消息。 2. 调查本地网络和防火墙规则,以确保它们没有阻止与 Cloudflare Tunnel IP 和端口的连接。 |
有关更多信息,请参阅 Cloudflare 1xxx 错误综合列表。
隧道路由上出现带有 Unable to reach the origin service. The service may be down or it may not be responding to traffic from cloudflared 的 502 Bad Gateway 错误,表示隧道本身已连接到 Cloudflare 网络,但 cloudflared 无法访问您的入站规则中定义的源服务。与错误 1033(表示隧道未连接到 Cloudflare)不同,502 错误表明问题出在 cloudflared 和您的本地服务之间。
要找出具体原因,请查看您的隧道日志中的 error 级别消息。常见原因包括:
如果源服务已停止或从未启动,cloudflared 日志将显示类似以下的错误:
error="dial tcp [::1]:8080: connect: connection refused"要解决此问题,请验证服务是否正在运行并在预期端口上监听:
curl -v http://localhost:8080如果服务未运行,请启动或重启它。您可以通过运行 ss -tlnp | grep <PORT>(Linux)或 lsof -iTCP -sTCP:LISTEN -nP | grep <PORT>(macOS)来确认服务是否在监听。
如果源站期望 HTTPS 但隧道路由指定了 http://,反之亦然,cloudflared 日志将显示类似以下的错误:
error="net/http: HTTP/1.x transport connection broken: malformed HTTP response \"\\x15\\x03\\x01\\x00\\x02\\x02\""要解决此问题,请将隧道路由中的服务 URL 更新为与源站期望的协议匹配。例如,将 http://localhost:8080 更改为 https://localhost:8080。如果您使用的是本地管理的隧道,请更新配置文件中的入站规则。
如果隧道路由中的端口与您的服务正在监听的端口不匹配,cloudflared 将为该端口记录 connection refused 错误。请仔细检查您的入站规则中的服务 URL,并与您的应用程序绑定的端口进行比较。
如果源站提供了 cloudflared 无法验证的 TLS 证书,日志将显示类似以下的错误:
error="x509: certificate is valid for example.com, not localhost"当源站使用自签名证书或 SSL/TLS 检测代理位于 cloudflared 和源站之间时,通常会发生这种情况。
要解决此问题,请使用以下方法之一:
将
originServerName设置为您隧道路由中源站证书上的主机名。如果您使用的是本地管理的隧道,以下是配置文件示例:ingress: - hostname: app.example.com service: https://localhost:443 originRequest: originServerName: app.example.com使用
caPool提供 CA 证书:ingress: - hostname: app.example.com service: https://localhost:443 originRequest: caPool: /path/to/ca-cert.pem作为最后手段,使用
noTLSVerify禁用 TLS 验证。不建议在生产环境中使用此方法。ingress: - hostname: app.example.com service: https://localhost:443 originRequest: noTLSVerify: true
当 cloudflared 无法识别您的源站提供的 SSL/TLS 证书时,会发生此错误。要解决此问题,请将源服务器名称参数设置为您源站证书上的主机名。以下是本地管理的隧道配置示例:
ingress:
- hostname: test.example.com
service: https://localhost:443
originRequest:
originServerName: test.example.com这意味着您的 cloudflared access 客户端无法访问您的 cloudflared tunnel 源站。要诊断此问题,请查看 cloudflared tunnel 日志。常见根本原因是 cloudflared tunnel 无法代理到您的源站(例如,因为入站配置错误、源站宕机或 cloudflared tunnel 无法验证源站 HTTPS 证书)。如果 cloudflared tunnel 没有日志,则表示 Cloudflare 网络无法将 WebSocket 流量路由到它。
此错误有以下几种可能的根本原因:
- 您的
cloudflared tunnel未运行或未连接到 Cloudflare 网络。 - WebSocket 未启用。
- 您的 Cloudflare 账户已启用通用 SSL,但您的 SSL/TLS 加密模式设置为 Off (Not Secure)(关闭(不安全))。要解决此问题,请在 Cloudflare 仪表板中转到 SSL/TLS > Overview(概览),将 SSL/TLS 加密模式设置为 Flexible(灵活)、Full(完全) 或 Full (strict)(完全(严格))。
- 您的请求被 Super Bot Fight Mode 阻止。要解决此问题,请确保在机器人对抗模式设置中将明确的自动化设置为_允许_。
- 您的 SSH 或 RDP Access 应用程序已启用绑定 Cookie。要禁用此 Cookie,请转到 Access controls(访问控制) > Applications(应用程序) 并编辑应用程序设置。
- 一个或多个 Workers 路由与隧道主机名重叠,而 Workers 未正确处理流量。要解决此问题,请通过不定义包含隧道主机名的路由来将您的隧道排除在 Worker 路由之外,或者更新您的 Worker 以仅处理特定路径并将所有其他请求转发到源站(例如,使用
return fetch(req))。
如果 cloudflared 返回错误 error="remote error: tls: handshake failure",请检查相关主机名是否有 SSL 证书覆盖。如果使用多级子域名,可能需要高级证书,因为通用 SSL 不覆盖超过一级的子域名。这可能在浏览器中显示为 ERR_SSL_VERSION_OR_CIPHER_MISMATCH。
如果您的Cloudflare Tunnel 日志返回 socket: too many open files 错误,表示 cloudflared 已耗尽您机器上的打开文件限制。最大打开文件数(或文件描述符数)是操作系统设置,用于确定一个进程允许打开多少个文件。要提高打开文件限制,您需要在运行 cloudflared 的机器上配置 ulimit 设置。
此缓冲区大小增加由 cloudflared ↗ 利用的 quic-go 库 ↗报告。您可以在 quic-go 仓库 ↗中了解有关此日志消息的更多信息。此日志消息通常不会产生影响,在故障排查时可以安全忽略。但是,如果您在高带宽的特殊环境中部署了 cloudflared,则可以手动覆盖缓冲区大小以进行测试。
要在 Linux 上设置最大接收缓冲区大小:
-
在
/etc/sysctl.d/下创建一个新文件:sudo vi 98-core-rmem-max.conf -
在文件中定义所需的缓冲区大小:
net.core.rmem_max=2500000 -
重启运行
cloudflared的主机。 -
要验证这些更改是否已生效,请使用
grep命令:sudo sysctl -a | grep net.core.rmem_maxnet.core.rmem_max = 2500000
除非源服务器包含 Content-Type: text/event-stream 响应头,否则通过 Cloudflare Tunnel 代理的流量默认会被缓冲。此响应头告知 cloudflared 在数据到达时进行流式传输,而不是缓冲整个响应。
为了尽可能快地进行故障排除,请确保您的支持工单包含详尽的详细信息。您提供的上下文越多,识别和解决您问题的速度就越快。
为了确保在 联系支持人员 时能够高效解决问题,请在工单中包含尽可能多的相关细节:
要捕获用于故障排除的详细输出:
-
本地管理的隧道:使用
--loglevel debug标志运行cloudflared:cloudflared tunnel --loglevel debug run要将日志持久化到文件中,添加
--logfile标志:cloudflared tunnel --loglevel debug --logfile /var/log/cloudflared/cloudflared.log run
在联系支持人员时请附上调试日志 — 有关要包含的信息的完整列表,请参阅上面的清单。