Cloudflare Tunnel 内网穿透:不碰防火墙,也能把服务挂上公网
家里 NAS 上的相册、本地跑的服务、测试中的网站,想从外网打开时,多数教程会直接教你开端口。但开端口之前值得先停一下:有没有一种办法,既不用公网 IP,也不用在防火墙上打洞?Cloudflare Tunnel 就是为这个需求生的。
先对比:四种把内网服务挂上公网的方式
| 方式 | 要不要公网 IP | 要不要开入站端口 | 安全性 | 适合谁 |
|---|---|---|---|---|
| 路由器端口转发 | 需要 | 需要 | 较低,端口直接暴露给扫描器 | 临时调试、能接受风险的人 |
| DDNS + 端口转发 | 动态 IP 也得有公网 IP | 需要 | 较低,和上一行同款风险 | 动态 IP 家庭宽带 |
| VPS 反向代理 | 无需(VPS 自带) | VPS 侧需要 | 中等,入口收敛到一台机器 | 已有 VPS 且愿意维护的人 |
| Cloudflare Tunnel | 无需 | 无需 | 较高,全部是出站连接 | 想省心、不想碰防火墙的人 |
如果你符合最后一行的描述,后面就是你的菜;如果你已经有 VPS 且就喜欢自己掌控反代,那也不必为了换而换。
原理换个说法:不是开门,是打电话
传统穿透是在墙上开个洞等人进来,洞开着,扫描器就能找到。Tunnel 的方向正好反过来:你家里的机器主动运行一个叫 cloudflared 的连接器,像打电话一样向 Cloudflare 的边缘节点拨出一条加密通道并保持在线。有人从外网访问你的域名时,Cloudflare 就沿着这条现成的通道把请求递进来——墙上没有任何新开的洞,扫你的 IP 也找不到服务。
这个方向差异就是 Tunnel 安全性的全部来源:入站端口一个都不用开。
建隧道:Zero Trust 里走一遍
前置条件只有两个:域名解析已经托管在 Cloudflare,以及一个开启了 Zero Trust 的账号(会要求绑定支付方式,但核心功能不收费)。
- 进 Cloudflare 控制台的 Zero Trust,到 Networks → Tunnels,点 Add a tunnel,起个名字,比如
homelab-main。 - 按页面给的命令在你的机器上装连接器。用 Docker 是最省事的一种:
docker run -d --name cloudflared \
cloudflare/cloudflared:latest tunnel --no-autoupdate run --token <你的TOKEN>- 回到网页端,看到隧道状态变成 HEALTHY,说明出站通道已经通了。
- 进 Public Hostname,点 Add a public hostname:域名填
home.yourdomain.com这类,本地服务地址填http://192.168.1.20:3000这类。保存后等几秒,https://home.yourdomain.com就能打开内网服务了。
注意第 2 步的 token 是敏感信息,别贴到公开聊天记录、截图或仓库里。
再加一道锁:登录墙
隧道通了只是第一步,对外服务建议再加一道身份验证。Cloudflare Access 能在隧道入口再加一层身份检查:访客必须先通过邮箱验证码、GitHub 登录或 2FA 其中一种,Cloudflare 才放行到内网服务。这相当于免费给所有内网服务套了一个企业级登录页,尤其适合相册、管理后台这类“只给自己和家人看”的服务。
局限与取舍:用之前先知道
| 局限 | 影响 | 怎么应对 |
|---|---|---|
| 流量绕道 Cloudflare 节点 | 国内非优化线路访问可能比直连慢 | 对速度敏感的服务走 VPS 反代,别硬套隧道 |
| 非 HTTP 协议支持较绕 | SSH、RDP 这类协议免费版要客户端也装 cloudflared | 纯网页服务无影响;SSH 需求多的人评估后再选 |
| 依赖 Cloudflare 可用性 | 边缘节点出问题会影响访问 | 关键服务留一条备用入口,别把所有鸡蛋放一个篮子 |
排障:先查这三处
- 隧道状态不是 HEALTHY:先看连接器容器是不是在跑、token 有没有贴错,多数问题出在这两处。
- 域名能解析但打不开服务:核对 Public Hostname 里填的本地地址和端口,服务本身要在内网先能访问。
- 加了 Access 后自己也进不去:先确认登录方式绑的是你自己的账号或邮箱,再看策略是不是把自己也拦在了外面。
延伸阅读
免责声明
本文仅供技术交流和学习参考。涉及第三方服务的链接可能包含 sponsored 标记,请自行核实服务条款、价格和可用性,并遵守当地法律法规。