Cloudflare Tunnel 把内网服务暴露出去
以前想让外网访问家里的服务,路子无非两条:要么在路由器上做端口映射并暴露公网 IP,要么租一台有公网 IP 的 VPS 做反向代理。
这两种做法都有个共同的毛病——你确实在公网上开了一个入口。哪怕只转发 443,扫描器也会很快找上门。
Cloudflare Tunnel 换了思路:连接是从内网主动向外建立的,公网侧根本不存在可以扫描的入站端口。
原理
访客 → Cloudflare 边缘节点 →(已经建好的长连接)→ cloudflared → localhost:3000
cloudflared 进程在你这台机器上跑着,启动时主动连到 Cloudflare 并保持一条隧道。外部请求到达边缘节点后,顺着这条已建立的连接回传进来。
所以:
- 路由器上不需要开任何端口
- 不需要公网 IP,NAT 后面就行
- 出口流量,防火墙通常不会拦
基本用法
先登录并创建隧道:
cloudflared tunnel login
cloudflared tunnel create my-blog
然后把本地服务和域名绑起来:
cloudflared tunnel route dns my-blog blog.example.com
配置文件 ~/.cloudflared/config.yml:
tunnel: ff19965a-1b58-45e6-91bc-6d1d2202293c
credentials-file: /home/user/.cloudflared/ff19965a-....json
ingress:
- hostname: blog.example.com
service: http://localhost:3000
# 兜底规则必须放最后,否则 cloudflared 会拒绝启动
- service: http_status:404
最后那个 http_status:404 是必需的——少了它 cloudflared 会启动失败,因为 ingress 规则要求有一个不带 hostname 的兜底项。
几个实际会踩的点
DNS 记录要指向隧道。 用 tunnel route dns 命令加出来的记录是一条 CNAME,指向 <隧道ID>.cfargotunnel.com,而且必须保持**橙色云朵(已代理)**打开。手动改成 DNS only 就废了。
Windows 上装成服务。 想让隧道开机自启、后台常驻:
cloudflared service install
区分「隧道」和「DNS」两套权限。 Cloudflare 的 API Token 权限粒度很细,一个能改 DNS 的 Token 未必能管理隧道——Account → Cloudflare Tunnel → Edit 是另一个独立权限。报 9109 的时候先怀疑这个,而不是怀疑 Token 写错了。
和 Pages 怎么选
| Cloudflare Tunnel | Cloudflare Pages | |
|---|---|---|
| 需要常开的机器 | 是 | 否 |
| 适合动态服务 | 是 | 否(纯静态) |
| 全球加速 | 依赖源站 | 原生 CDN |
| 运维成本 | 中 | 几乎为零 |
结论挺简单:静态博客用 Pages,动态服务才上 Tunnel。 让一台机器整年开着只为托管几页 Markdown,实在没必要。
不过 Tunnel 有个 Pages 替代不了的优势:本地开发环境可以挂个域名直接给同事看,改完代码刷新即生效,不用重新部署。
评论