Cloudflare Tunnel 完全指南:从零搭建到进阶玩法
摘要
本文详细介绍了 Cloudflare Tunnel 内网穿透方案,涵盖从基础操作(Quick Tunnel、Dashboard、配置文件)到进阶玩法(身份认证、SSH 隧道、动态 IP 白名单、速度优化、负载均衡)。文章对比了其优势,并提供了避坑清单,适合希望安全、便捷地暴露内网服务的开发者参考。
前言
一条命令就能让内网服务拥有公网地址,还有自动 HTTPS 和 DDoS 防护——Cloudflare Tunnel 可能是你用过的最省心的内网穿透方案。但这只是冰山一角。本文从最基础的操作开始,逐步解锁多服务路由、身份认证、SSH 隧道、动态 IP 白名单、配置文件模式和速度优化等进阶玩法。
如果你只是想了解Cloudflare Tunnel 最基本的用法,看我之前的文章就可以了,五分钟就可以设置完成,这篇文章主要是为了记录我最近的学习成果,现在用不到的功能以后也许就用到了。
一、它到底是什么
传统内网穿透的逻辑是"打洞"——开放端口,让外部流量直接钻进来。Cloudflare Tunnel 反过来:你的服务器主动往外连,和 Cloudflare 全球边缘网络建立加密长连接;外部用户访问域名时,流量先到 Cloudflare,再沿这条隧道转发回你的本机。
这意味着:
不需要公网 IP
不需要路由器端口映射
源站地址天然隐藏(攻击者扫不到你的真实 IP)
自动 HTTPS(Cloudflare 自动签证书)
自带 WAF + DDoS 防护 + Bot 管理
一个直觉上的对比:frp / ngrok 是你自己租了一辆出租车,司机是你,路线你定;Cloudflare Tunnel 是你搭上了 Cloudflare 的全球公交系统,免费,班次密,车身自带装甲。
二、基础教程:三种上手路径
根据你的需求急迫程度,有三种起步方式。建议按顺序体验:先用 Quick Tunnel 感受效果,再用 Dashboard 创建正式隧道,最后用配置文件管理多服务。
2.1 Quick Tunnel——30 秒体验
不需要域名,不需要账号,一条命令就能拿到一个临时公网地址。
输出类似:
浏览器打开这个地址,就能访问你的本地服务了。
适合场景:临时演示、本地调试 webhook、给同事看开发中的页面。
三个限制必须知道:
域名每次重启都会变(随机生成)
不支持长连接(WebSocket 等可能不稳定)
并发请求有限制
所以 Quick Tunnel 只适合临时测试,正式服务请走下一步。
2.2 Dashboard 创建正式隧道——绑定自己的域名
这是最推荐的入门方式。全程在 Cloudflare 控制台操作,不需要写配置文件。
前置条件:
Cloudflare 账号
一个已托管在 Cloudflare 的域名
本机能访问互联网(如果防火墙严格,需确认出站端口 7844 可达)
步骤:
① 创建隧道
进入 Cloudflare Dashboard → Zero Trust → Networks → Tunnels → Create Tunnel
选择 "Cloudflared",给隧道起个名字(比如nosp),保存。
② 安装 cloudflared
页面会根据你选择的操作系统生成安装命令。几种常见方式:
③ 启动隧道
复制页面给的 Token 命令,在本机执行:
或者用 Docker(更干净,推荐):
Docker Compose 写法更方便管理:
⚠️ TUNNEL_TOKEN 是高危凭据。拿到它的人可以把自己的 cloudflared 接到你的隧道上。绝不提交到公开仓库,绝不截图发到公共论坛。
④ 配置公共主机名
回到 Dashboard,选择你刚创建的隧道,点击 "Configure" → "Public Hostname" → "Add a public hostname"。
填写:
字段 | 示例 |
|---|---|
Subdomain |
|
Domain |
|
Type | HTTP |
URL |
|
保存后,Cloudflare 自动创建一条 CNAME DNS 记录,把 nas.yourdomain.com 指向 <TUNNEL_ID>.cfargotunnel.com。
浏览器打开 https://nas.yourdomain.com ——你的 NAS 面板已经在公网上了,自带 HTTPS。
⑤ 验证隧道健康
Dashboard 上隧道状态变成 Healthy(绿色),说明 cloudflared 已经成功和 Cloudflare 建立连接。
2.3 配置文件模式——管理多服务的最佳方式
当你有超过 2-3 个服务要暴露时,在 Dashboard 上逐个点 "Add hostname" 就变得繁琐。这时候切换到配置文件模式,一切都在 YAML 里管理。
① 登录授权
浏览器会打开授权页面,选择你的域名。授权后本地生成 ~/.cloudflared/cert.pem。
② 创建隧道
记下输出的 <TUNNEL_ID>(UUID 格式)。
③ 写配置文件
创建 ~/.cloudflared/config.yml:
关键规则:ingress 按顺序匹配,最后一条必须是兜底规则(没有 hostname 的 catch-all)。官方文档要求如此,否则 cloudflared tunnel ingress validate 会报错。
④ 注册 DNS
每条命令会在 Cloudflare DNS 里自动创建 CNAME 记录。
⑤ 验证配置 + 启动
Linux 上会自动注册为 systemd 服务(/etc/systemd/system/cloudflared.service),支持开机自启和自动重启。
三、进阶玩法一:给服务加身份认证
暴露到公网的服务如果没有任何认证,等于裸奔。Cloudflare Tunnel 解决的是"怎么安全连到源站",但不等于自动给你的应用加了登录系统。
NAS 面板、Git 后台、数据库管理界面这类敏感服务,必须加一层 Cloudflare Access。
3.1 邮箱认证——最简单的门槛
步骤:
Zero Trust → Access → Applications → Add application → Self-hosted
填写应用名称,添加公共主机名(如
nas.yourdomain.com)创建访问策略:
Action:Allow
Include:Emails → 填入允许访问的邮箱地址
保存策略,关联到应用程序
效果:访问nas.yourdomain.com时,先跳转到 Cloudflare 的认证页面,输入邮箱后收到验证码,验证通过才能进入。不在这个邮箱列表里的人,连页面都看不到。
3.2 OAuth 认证——Google / GitHub 一键登录
策略里把 Include 改为 Identity Provider Groups,选择 Google 或 GitHub 等 IdP。用户一键登录,比邮箱验证码体验更好,也更安全(自带 MFA)。
3.3 多层策略——白名单 + 认证组合
你可以给同一个应用配置多条策略,按优先级执行:
优先级 | 策略类型 | 效果 |
|---|---|---|
1 | Bypass(IP List) | 白名单 IP 直接放行,不弹认证 |
2 | Allow(Email) | 其他 IP 需邮箱验证 |
这样做的好处:家里局域网的 IP 可以免认证直通,在外面则必须验证身份。
四、进阶玩法二:SSH 隧道——远程运维的隐藏大招
Cloudflare Tunnel 不只能转发 HTTP。把 SSH 也接进来,你的服务器就不需要开放 22 端口,跨境连接也更稳定。
4.1 服务端配置
4.2 客户端配置
本机安装 cloudflared,然后修改 ~/.ssh/config:
之后直接:
流程是这样的:
SSH 客户端调用
cloudflared access ssh作为 ProxyCommand本地 cloudflared 拉起浏览器,完成 Zero Trust 认证
认证通过后签发访问令牌
流量沿 Tunnel 到达服务器 localhost:22
为什么比直连 SSH 更稳定:跨境链路(比如德国到中国联通)经常出现Connection reset by peer。Tunnel 把 SSH 流量包在 HTTPS 长连接里,绕过了运营商对 22 端口的干扰。
安全层面:配合 Zero Trust Access,只有指定邮箱 / IdP 账号才能拿到令牌。就算有人知道ssh.yourdomain.com,也连不上。
五、进阶玩法三:动态 IP 白名单——适配不支持认证的客户端
有些客户端(比如某些 IoT 设备、旧版 App)不支持浏览器认证弹窗。这时候可以用 Cloudflare Worker 做动态 IP 白名单:用户先在浏览器完成一次认证,IP 就被加入白名单,后续请求自动放行。
5.1 原理
用户访问一个 Worker 注册页面(如
register.yourdomain.com)完成邮箱 / IdP 认证后,Worker 把用户当前 IP 写入 Cloudflare IP List + KV 存储(带过期时间)
原服务的 Access 策略里加一条 Bypass(IP List)
白名单 IP 请求直通,其他 IP 需认证
5.2 部署步骤(使用开源项目)
项目地址:cloudflare_dynamic_ip_list
然后在 Zero Trust 里配置:
原服务的 Access 策略,优先级最高加一条 Bypass(IP List)
Worker 注册页面的 Access 策略,用邮箱或 IdP 认证
使用方式:浏览器访问注册页面,认证一次,IP 自动入白名单。对于不支持认证的客户端,可以用 iOS 快捷指令 / cron 任务带CF-Access-Client-Id和CF-Access-Client-Secret请求头自动注册。注意:自动化任务可能无法控制 IPv 4 / IPv 6 地址,建议多请求几次确保两种地址都被注册。
六、进阶玩法四:速度优化——优选 IP 加速
国内直连 Cloudflare 边缘节点的延迟有时不理想。社区流传的"优选 IP"方案,利用 Cloudflare for SaaS 功能,让用户通过自选的快速 IP(或第三方优选域名)接入你的 Tunnel 服务。
6.1 原理
正常流程:用户 → Cloudflare 边缘(就近节点)→ Tunnel → 源站
优选流程:用户 → 自选快速 IP / 优选域名 → Cloudflare for SaaS 回退到你的域名 → Tunnel → 源站
核心是 Cloudflare for SaaS 的 "Fallback Origin" 机制:你可以把一个域名作为 SaaS 客户的回退源,当外部域名(优选域名)解析到 Cloudflare IP 时,Cloudflare 会把请求路由到你的回退源域名,再沿 Tunnel 转发。
6.2 配置步骤
① 在 Cloudflare 控制台开启 SaaS
进入 SSL/TLS → Custom SSL/TLS → Edge Certificates → Cloudflare for SaaS
添加回退源(Fallback Origin):填你的主域名(如
yourdomain.com)添加自定义主机名(Custom Hostname):填优选域名(如
cdn.bestcf.one)
② DNS 配置
优选域名的 CNAME 指向你自选的 Cloudflare IP(社区有大量优选 IP 列表)
或者 CNAME 指向已验证的优选域名
③ 验证
Cloudflare for SaaS 会给自定义主机名发一个验证 TXT 记录,按提示在优选域名的 DNS 里添加即可。
④ Nginx 反向代理(可选)
如果想在本机做更细的路由控制,可以在 cloudflared 和源站之间加一层 Nginx:
Nginx 配置示例:
注意:Tunnel 公共主机名里的 URL 填 Nginx 地址(如
http://localhost:80),而不是直接填服务地址。这样 Nginx 做中间层,可以统一管理路由、缓存和 WebSocket 代理。
七、进阶玩法五:负载均衡与高可用
一个 Tunnel 默认维护多条长连接,连到不同的 Cloudflare 数据中心。但你还可以更进一步。
7.1 多实例冗余
原理:多个 cloudflared 实例可以连接到同一个隧道 UUID。Cloudflare 会自动在多个实例之间分发流量。
Dashboard 上会显示两个连接都 Healthy。如果 A 挂了,流量自动走 B。
7.2 多隧道分工
不同环境用不同隧道,互不影响:
每个隧道有独立的 config.yml、独立的 credentials-file、独立的 DNS 路由。
八、避坑清单
踩过的坑都帮你整理好了:
8.1 本地服务监听地址不对
如果你的服务只监听容器内部地址(如 127.0.0.1:8080 而非 0.0.0.0:8080),cloudflared 在另一个容器里可能连不上。
排查:在运行 cloudflared 的机器上 curl 你的服务地址,如果本机都访问不了,Tunnel 也转发不了。
8.2 防火墙拦了出站连接
Tunnel 不需要入站端口,但 cloudflared 需要主动连出去。公司网络、云安全组如果拦截了出站流量(尤其是端口 7844),隧道会一直显示 Unhealthy。
排查:检查出站策略,确认能访问 Cloudflare 的连接端口。
8.3 域名没托管在 Cloudflare
公共主机名需要域名托管在 Cloudflare 才能自动创建 DNS 路由。如果你的域名在别处管理,要么迁移到 Cloudflare,要么手动在原 DNS 服务商添加 CNAME 记录指向 <TUNNEL_ID>.cfargotunnel.com。
8.4 Docker 容器网络隔离
cloudflared 容器和服务容器在不同的 Docker network 里时,localhost 互相不通。
解决方案:
8.5 WebSocket 连不上
某些服务(如 Home Assistant、n8n)依赖 WebSocket。Cloudflare Tunnel 默认支持,但如果中间有 Nginx 代理,需要显式配置 WebSocket 升级头:
8.6 Tunnel Token 泄露
Token 一旦泄露,攻击者可以把自己的 cloudflared 接到你的隧道上。建议:
不提交到 Git 仓库
用环境变量传递,不硬编码在 docker-compose.yml 里
定期在 Dashboard 上检查隧道连接数是否异常
九、常用命令速查表
十、方案对比:什么时候选 Cloudflare Tunnel
特性 | Cloudflare Tunnel | frp | Tailscale |
|---|---|---|---|
是否需要公网 IP | ❌ 不需要 | ✅ 中继服务器需要 | ❌ 不需要 |
是否需要域名 | ✅ 推荐有 | ❌ 不需要 | ❌ 不需要 |
自动 HTTPS | ✅ 自动 | ❌ 需自配 | ❌ 需自配 |
DDoS 防护 | ✅ 自带 | ❌ 无 | ❌ 无 |
身份认证 | ✅ Access | ️ 需自配 | ✅ 内置 |
非 HTTP 服务 | ✅ 需客户端 cloudflared | ✅ 原生支持 | ✅ 原生支持 |
速度(国内) | 中等(可优选 IP 加速) | 快(自选节点) | 快(P 2 P+DERP) |
适合场景 | 公开 Web 服务 + 安全暴露 | 私有内网穿透 | 私有网络互连 |
搭配建议:Tailscale 负责私有设备互连(手机连 NAS、开发机连服务器),Cloudflare Tunnel 负责把特定服务公开到域名上(博客、API、演示站)。两者互补,不冲突。
写在最后
Cloudflare Tunnel 的门槛极低——一条命令就能拿到公网地址。但它的天花板远不止于此:
Quick Tunnel 是体验入口
Dashboard + Docker 是日常用法
config.yml + Access 是生产标配
SSH 隧道 + 动态 IP 白名单 + 优选 IP 是深度玩家的领地
从"让本地服务能被外部访问"到"让外部只能以你允许的方式访问",中间的每一步,Cloudflare 都已经把工具准备好了。剩下的,就是你怎么组合它们。