Cloudflare 隧道

#Cloudflare #技术 #TIL

我偶尔需要将本地机器上运行的服务暴露到互联网,通常只是临时性的。与其在路由器上开放端口或折腾防火墙规则,反向隧道就能很好地完成这项工作。

有不少提供商提供这种反向隧道服务,包括:[1]

我最近一直在折腾 Cloudflare Tunnel。它的客户端 cloudflared 支持几种不同的模式:匿名的快速隧道(临时的、随机命名的 URL),以及与 Cloudflare 账户绑定的命名隧道,后者能提供稳定、可预测的主机名。

快速隧道

如果只是想把某个东西放到公共 URL 上共享一小时,TryCloudflare 无需账户,只需 cloudflared 这个二进制文件即可。例如,要共享监听 8080 端口的本地 Web 服务器:

cloudflared tunnel --url http://localhost:8080

cloudflared 会向外连接到 Cloudflare 的边缘网络,并打印出一个随机生成的 URL:

https://some-random-words-here.trycloudflare.com

任何拿到该 URL 的人都可以通过 Cloudflare 的网络访问你的本地服务器。

在依赖这些之前,有几个注意事项值得了解:

  • 隧道及其 URL 只存在于 cloudflared 进程运行期间。按 Ctrl-C 它就消失了,下次启动时会得到一个全新的随机 URL。
  • 它们仅用于测试和开发。

命名隧道

对于需要长期使用的情况,命名隧道能提供你自定义的稳定主机名。这需要登录 Cloudflare 账户,并且需要一个由 Cloudflare DNS 托管的域名。

首先,进行身份验证并创建隧道:

# 打开浏览器窗口进行身份验证
cloudflared tunnel login

# 创建隧道和凭证文件(~/.cloudflared/<UUID>.json)
cloudflared tunnel create my-tunnel

# 确认它已存在
cloudflared tunnel list

接下来,在 ~/.cloudflared/config.yml 创建配置文件,将主机名映射到本地服务:

tunnel: <UUID>
credentials-file: /home/you/.cloudflared/<UUID>.json

ingress:
  # 将公共主机名映射到本地服务
  - hostname: app.my-site.com
    service: http://127.0.0.1:8080

  # 必需的兜底规则;任何未匹配的请求都会返回 404
  - service: http_status:404

Ingress 规则按从上到下的顺序求值,最后一条必须是兜底规则。服务可以不只是普通的 HTTP:还支持 SSH、RDP、任意 TCP、Unix 套接字等等。其他顶层选项(如 protocoledge-ip-version)可以调整 cloudflared 连接边缘网络的方式。

然后,将 DNS 记录路由到隧道并启动它:

# 为 app.my-site.com 创建 CNAME
cloudflared tunnel route dns my-tunnel app.my-site.com

# 开始提供流量
cloudflared tunnel run my-tunnel

还有几个对调试有用的命令:

# 检查配置中的 ingress 规则是否正确
cloudflared tunnel ingress validate

# 检查给定 URL 会匹配哪条规则
cloudflared tunnel ingress rule https://app.my-site.com

# 查看运行中隧道的连接状态
cloudflared tunnel info my-tunnel

总的来说,这些命令提供了一种快捷方便的方式,可以将本地机器上的工具和服务暴露到互联网。尤其是当你已经把 Cloudflare 用作站点的 DNS 时。

  1. 由于这个博客托管在 Cloudflare Pages,这自然是我首先尝试的选择。它完成了我需要的所有事情——所以我最终没有尝试这个列表中的其他条目。