Cloudflare Tunnel:零端口暴露的内网穿透方案
把内网服务发布到公网,传统方案是 frp / ngrok / 端口转发——都要么需要一台公网 VPS 当跳板,要么要花钱买套餐,要么得在路由器开端口。
Cloudflare Tunnel 是 CF 提供的免费方案:装一个客户端(cloudflared),它主动和 CF 的边缘建立反向连接,外网通过你的域名访问,全程 HTTPS,没有任何入站端口暴露。
一、为什么用 CF Tunnel
对比一下主流方案:
| 方案 | 公网 IP | 端口转发 | 费用 | HTTPS | DDoS 防护 |
|---|---|---|---|---|---|
| frp 自建 | 需要跳板 VPS | 是 | VPS 费用 | 需手动 | 无 |
| ngrok 免费版 | 不需要 | 否 | 免费但限速/限连接 | 自动 | 无 |
| 端口转发(路由器) | 需要 | 是 | 0 | 需手动 | 无 |
| CF Tunnel | 不需要 | 否 | 0 | 自动 | 有 |
适用场景:
- 家里跑了 NAS / Jellyfin / HomeAssistant,想在外面访问
- 小公司内网服务想给远程同事用,但没有公网 IP
- 临时把开发环境 demo 给别人看
- 树莓派跑了几个服务想公开
二、工作原理
主动从内网发起| CL[cloudflared 客户端
跑在你内网机器上] CL --> S[内网服务
localhost:8080]
关键点:
- cloudflared 主动连 CF,不需要内网开任何端口
- 流量走 CF → cloudflared → 本地服务
- 全程 TLS 加密,外网看到的是 CF 的 IP,不是你的真实 IP
三、准备工作
| 项目 | 要求 |
|---|---|
| 域名 | 已托管到 Cloudflare(必须) |
| 内网机器 | Linux / macOS / Windows / 路由器 / Docker 都能跑 |
| Cloudflare 账号 | 免费版就够 |
如果你的域名还没在 CF:先去 dash.cloudflare.com → Add Site → 跟着指引改 NS。
四、操作步骤(推荐 Dashboard 方式)
CF 现在主推 Zero Trust Dashboard 配置 Tunnel,比命令行方式直观。
4.1 进入 Zero Trust
CF 控制台 → 左侧 Zero Trust → 第一次会让你选个 Team 名(随便起)。
4.2 创建 Tunnel
Networks → Tunnels → Create a tunnel:
| 步骤 | 操作 |
|---|---|
| Connector type | 选 Cloudflared |
| Tunnel name | 随便起,如 home-nas |
| Save | 保存后会给你安装命令 |
4.3 在你的内网机器上跑 cloudflared
CF 会给一段类似这样的命令(不同平台不一样):
# Linux (Debian/Ubuntu)curl -L --output cloudflared.deb \ https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.debsudo dpkg -i cloudflared.deb
# 服务化 + 用 CF 给你的 token 注册sudo cloudflared service install <YOUR-TUNNEL-TOKEN># Windows# 下载 https://github.com/cloudflare/cloudflared/releases 里的 .msi 安装cloudflared.exe service install <YOUR-TUNNEL-TOKEN># Dockerdocker run -d \ --name cloudflared \ --restart unless-stopped \ cloudflare/cloudflared:latest \ tunnel --no-autoupdate run --token <YOUR-TUNNEL-TOKEN>跑起来后回到 Dashboard,Connector 状态变成 HEALTHY。
4.4 配置 Public Hostname
Public Hostname → Add a public hostname:
| 字段 | 值 |
|---|---|
| Subdomain | nas(最终是 nas.your-domain.com) |
| Domain | 选你的域名 |
| Service Type | HTTP / HTTPS / SSH / RDP / TCP 等 |
| URL | localhost:8080(内网服务的地址) |
保存。CF 会自动给你的子域名添加 CNAME 记录。
4.5 验证
curl -I https://nas.your-domain.com返回 200 / 301 等正常响应,整个流程跑通。
五、命令行方式(高级 / 想懂原理)
如果你想看到所有细节,命令行方式更清楚:
5.1 安装
curl -L --output cloudflared.deb \ https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.debsudo dpkg -i cloudflared.deb
cloudflared --version5.2 登录 + 授权
cloudflared tunnel login会打开浏览器让你选 zone,授权完后凭证存在 ~/.cloudflared/cert.pem。
5.3 创建 tunnel
cloudflared tunnel create home-nas会输出 tunnel UUID,并把凭证存到 ~/.cloudflared/<UUID>.json。
5.4 写配置文件
~/.cloudflared/config.yml:
tunnel: <你的 UUID>credentials-file: /home/youruser/.cloudflared/<UUID>.json
ingress: - hostname: nas.your-domain.com service: http://localhost:8080 - hostname: jellyfin.your-domain.com service: http://localhost:8096 - hostname: ssh.your-domain.com service: ssh://localhost:22 - service: http_status:404 # 兜底5.5 绑定域名 DNS
cloudflared tunnel route dns home-nas nas.your-domain.comcloudflared tunnel route dns home-nas jellyfin.your-domain.comcloudflared tunnel route dns home-nas ssh.your-domain.comCF 会自动加 CNAME。
5.6 跑 + 服务化
# 前台跑(测试)cloudflared tunnel run home-nas
# 服务化sudo cloudflared service installsudo systemctl status cloudflared六、典型应用场景
6.1 把家里的 Jellyfin 发布到公网
ingress: - hostname: video.your-domain.com service: http://localhost:8096 - service: http_status:404外网浏览器访问 https://video.your-domain.com → 看你 NAS 上的电影。
6.2 SSH 到内网机器(不用 frp)
服务端配置:
ingress: - hostname: ssh.your-domain.com service: ssh://localhost:22客户端要装 cloudflared 做转发:
# 本地 cloudflaredcloudflared access ssh --hostname ssh.your-domain.com
# 或者写到 ~/.ssh/configHost my-home HostName ssh.your-domain.com ProxyCommand cloudflared access ssh --hostname %h之后 ssh my-home 就能通到内网机器。
6.3 给路由器后台开公网入口
ingress: - hostname: router.your-domain.com service: https://192.168.1.1 originRequest: noTLSVerify: true # 路由器自签名证书要加这条⚠️ 把路由器后台暴露公网风险很大——建议配合下面的 Access 鉴权。
七、加上 Access 鉴权(必看)
CF Tunnel 默认是任何能访问域名的人都能进。一定要加访问控制。
Zero Trust → Access → Applications → Add an application:
| 设置 | 推荐 |
|---|---|
| Type | Self-hosted |
| Application domain | nas.your-domain.com |
| Policy → Action | Allow |
| Include | Emails / Email domains / Country / Device posture |
常用策略:
- Emails:只允许特定邮箱(输入 OTP 邮件验证码登录)
- Email domains:只允许
@your-company.com结尾 - Country: 仅允许中国 / 美国
- Service Token: 给 API/脚本访问用
加完之后,访问域名会先跳到 CF 的登录页,验证通过才进得去——免去自己写鉴权。
八、和 frp 对比
| 维度 | CF Tunnel | frp |
|---|---|---|
| 公网入口 | CF 边缘 IP | 你自己的 VPS IP |
| 协议 | HTTP/HTTPS(主)、TCP/SSH/RDP | 全协议 TCP/UDP |
| 配置复杂度 | 低(Dashboard 点点) | 中(写 ini 文件) |
| 自定义域名 | 必须用 CF 托管 | 任意 |
| 性能 | 走 CF 边缘,国内访问需绕 | 直连跳板 VPS,可选近 |
| 鉴权 | 内置 Access | 需自己加 |
| 国内访问 | CF 国内段速度不稳 | 选国内 VPS 跳板更快 |
💡 国内访问 NAS / 自部署服务,有时候 frp + 国内 VPS 反而更快。CF Tunnel 的优势在于”零配置 + 自带鉴权 + DDoS 防护”。
九、踩坑清单
| 现象 | 原因 | 解决 |
|---|---|---|
cloudflared service install 报错 | systemd 没启动 / 权限不够 | 用 sudo |
| Connector HEALTHY 但访问 502 | 内网服务没起 / 端口错 | curl localhost:端口 验证 |
| 自签名证书报错 | TLS 验证失败 | originRequest: noTLSVerify: true |
| 国内访问极慢 | CF 国内段不稳 | 考虑反代或换方案 |
| 配置了 Access 但还能匿名访问 | Policy 没启用 | Dashboard 双检 |
| Docker 跑的 cloudflared 连不上本机 | 默认 bridge 网络不通 host | 用 --network host |
| 改 config.yml 没生效 | 没 reload | cloudflared tunnel run 自动 / 服务化要 restart |
十、几条实用经验
- 能用 Dashboard 别命令行——CF 现在主推 Dashboard,文档也更新更勤。
- 一个 Tunnel 可以挂多个域名,不用每个服务建一个 Tunnel。
- 配 Access 是基操,没 Access 等于把内网门户开公网。
- 国内访问要测速:CF 国内出口偶尔不稳,跟优选 IP 那篇配合使用。
- 不要在主路由器上跑 cloudflared——和软路由 / OpenWrt 配合容易 NAT 链路混乱。挂在 NAS / 一台单独的小主机上更稳。
- cloudflared 升级很重要:CF 偶尔会让旧版客户端失效,建议开
--no-autoupdate关掉自动升级、自己定期手动升级,避免半夜被自动重启搞掉。
把这套配通,你的家里 / NAS / 任何内网服务都能用域名 + HTTPS 访问,再也不用折腾路由器端口转发。