Cloudflare Tunnel 内网穿透实战:免公网 IP、免备案,把 NAS 服务安全暴露到公网(含避坑与常见问题)

适用场景:飞牛 FnOS / 群晖 Synology / 极空间 ZSpace 等 NAS,或任意一台常开的小主机。 搭配上篇《家庭宽带只有 IPv6 也能全球访问》食用更佳——两篇文章分别解决「有 IPv6 想做双栈」和「什么公网地址都没有、只想免费穿透」两种需求。


一、为什么要用 Cloudflare Tunnel

先说痛点。想把家里的 NAS 服务(相册、笔记、网盘、面板)暴露到公网,传统路子的难处:

  • 没有公网 IP:现在家宽基本是大内网(CGNAT),连公网 IPv4 都拿不到,端口映射无从谈起。
  • 不想开放入站端口:即使有公网 IP,在光猫/路由器上开 80/443 转发,等于把家宽暴露在公网扫描下,运营商还经常封 80/443。
  • 不想备案:上篇说的 EdgeOne / 阿里云 CDN 方案很强,但国内节点必须 ICP 备案,嫌麻烦的人直接劝退。
  • 想要 HTTPS + DDoS 防护:自己搞证书和防护太累。

Cloudflare Tunnel(原名 Argo Tunnel,底层是 cloudflared 这个守护进程)正好对症下药:

  • 免费,个人使用无带宽费用;
  • 免备案,域名托管在 Cloudflare 即可;
  • 不需要公网 IP,也不需要开放任何入站端口;
  • ✅ 自动签发 HTTPS 证书,自带 CDN 缓存与 DDoS 防护;
  • 隐藏源站真实 IP,外面只能看到 Cloudflare 的边缘节点。

一句话:在你的 NAS 上跑一个 cloudflared,它主动「出站」连到 Cloudflare,公网用户经 Cloudflare 反向代理进来——你家宽带一个端口都不用开。


二、它到底是怎么工作的

flowchart LR
    U[公网用户] -->|HTTPS 请求| CF[Cloudflare 边缘节点]
    CF -->|已有加密隧道·出站连接| C[cloudflared<br/>跑在你的 NAS 上]
    C -->|localhost:端口| S[本地服务<br/>NAS/容器/应用]

核心是反向连接(reverse connection)

  • 传统内网穿透是「外面连进来」(需要在路由器上开端口、做转发);
  • Cloudflare Tunnel 是「里面连出去」——cloudflared 持续向 Cloudflare 建立一条长连接,完全出站,所以:
  • 你家防火墙/光猫无需任何入站规则
  • 源站 IP 永远不会暴露给公网访客。

原理理解到这一层,后面的坑基本都能想通。


三、什么情况适合 / 不适合

适合: - 没有公网 IP、不想备案,想快速把内部 Web 服务暴露出去; - 服务主要给海外 / 非中国大陆的朋友或自己访问; - 需要免费的 HTTPS、简单的访问控制。

不太适合(重要): - 主要给中国大陆用户访问:Cloudflare 在国内的节点质量很差,经常绕行海外、延迟高甚至被干扰。如果你的大部分访客在国内,上篇的 EdgeOne / 阿里云 CDN 方案更合适。 - 需要暴露 UDP 服务(见第十一节,CF Tunnel 不支持 UDP)。 - 大带宽、高并发的下载站(公平使用政策,别滥用)。


四、前置条件

  1. 一个域名,并且把 DNS 托管到 Cloudflare(在 Cloudflare 添加站点、改 NS 即可,域名本身可在任何注册商购买)。
  2. 一台常开设备cloudflared:NAS(Docker)、软路由、或一台小主机都行。
  3. Cloudflare 账号(免费版即可,Zero Trust 面板也是免费可用)。

五、步骤一:安装 cloudflared

最省事的是 Docker 一行(NAS 的 Container Manager / Docker 套件里跑):

docker run -d --name cloudflared --restart=always \
  --net=host \
  -v /opt/cloudflared:/home/nonroot/.cloudflared \
  cloudflare/cloudflared:latest \
  tunnel --no-autoupdate run

说明:--net=host 让容器直接用宿主机网络,映射 localhost 服务时最方便;配置目录挂载出来便于持久化。先别急着 run,下一步拿到凭证再填。

各系统原生安装(可选): - Debian/Ubuntu:apt install cloudflared 或官方 deb; - macOS:brew install cloudflared; - Windows:官方 exe 或 Docker。


六、步骤二:登录并创建 Tunnel

已经装好 cloudflared 的机器上操作(下面用宿主机原生命令示意,Docker 环境下把前缀换成 docker exec cloudflared ...):

# 1) 登录 Cloudflare(会打开浏览器让你授权域名)
cloudflared tunnel login

# 2) 创建一个命名隧道,名字随意
cloudflared tunnel create nas-home

# 3) 查看隧道列表,记住隧道的 UUID 和凭据文件路径
cloudflared tunnel list

login 成功后会在 ~/.cloudflared/ 生成 cert.pemcreate 会生成一个 <uuid>.json 凭据文件(这就是隧道的身份,别泄露)。


七、步骤三:写配置文件 config.yml

~/.cloudflared/config.yml(Docker 里对应挂载目录)写入:

tunnel: <你的隧道UUID>
credentials-file: /home/nonroot/.cloudflared/<UUID>.json

ingress:
  # 1) 网盘 / 相册等 Web 服务
  - hostname: drive.example.com
    service: http://localhost:8080

  # 2) NAS 管理面板
  - hostname: nas.example.com
    service: https://localhost:5001
    originRequest:
      noTLSVerify: true   # 源站是自签证书的群晖/飞牛时可跳过校验证书

  # 3) 任意 TCP(如 RDP 3389),需配合 Cloudflare Access + 客户端
  - hostname: rdp.example.com
    service: tcp://localhost:3389

  # 4) 兜底规则(必须放在最后,匹配所有未命中项)
  - service: http_status:404

⚠️ ingress 是从上往下匹配的,最后一定要有一条兜底规则,否则没匹配到的请求会报错。


八、步骤四:运行并设置开机自启

# 原生
cloudflared tunnel run nas-home

# Docker 方式:前面的 docker run 命令里 tunnel run 已就绪,
# 把 config.yml 放到挂载目录后启动容器即可

持久化(关键,否则重启就没了): - Docker--restart=always 已保证容器随宿主机启动; - 系统服务cloudflared service install 注册为系统服务(Linux);群晖/飞牛可在计划任务里加开机启动。

验证隧道在线:Cloudflare 后台 Zero Trust → Networks → Tunnels 里应显示 HEALTHY / 绿色。


九、步骤五:在 Cloudflare 后台加「公网主机名」

光有隧道还不够,要告诉 Cloudflare「哪个域名指向哪个本地服务」:

  1. 进入 Zero Trust → Access → Tunnels → 你的隧道 → Public Hostname
  2. 添加: - SubdomaindriveDomainexample.com; - Service TypeHTTP / HTTPS / SSH / TCP / RDP 等; - URLlocalhost:8080(与 config.yml 里一致)。
  3. 保存后,Cloudflare 会自动帮你把 drive.example.com 的 DNS(CNAME 到 *.cfargotunnel.com)建好。

等 DNS 生效(通常几十秒到几分钟),浏览器访问 https://drive.example.com 就能进来了。


十、进阶:SSH / 非 HTTP 服务怎么穿透

Cloudflare Tunnel 默认对 HTTP/HTTPS 最友好,浏览器直接开。但 SSH、RDP、数据库等「非 Web」协议要额外一步:

  • SSH(推荐用浏览器 Web SSH)
  • Service Type 选 SSH,URL 填 ssh://localhost:22
  • Access → Applications 里建一个 SSH 应用并开启 Browser SSH,访客直接在浏览器里输密码/密钥登录,无需本地客户端。
  • 也可以用本地客户端:cloudflared access ssh --hostname ssh.example.com
  • TCP(如 RDP 3389、MySQL 3306)
  • Service Type 选 TCP,URL 填 tcp://localhost:端口
  • 客户端侧需要 cloudflaredWARP 配合:cloudflared access tcp --hostname rdp.example.com --url localhost:3389,然后本地连 localhost:3389
  • 🚫 UDP 不支持:这是 Cloudflare Tunnel 的硬限制——WireGuard、OpenVPN(部分)、各类 UDP 游戏服务器等都无法通过 Tunnel 暴露。需要 UDP 穿透请另寻方案(如 WireGuard+公网服务器、或 ZeroTier/Tailscale 这类 P2P VPN)。

十一、安全加固(别裸奔)

  1. 管理后台务必加 Cloudflare Access 鉴权:把 nas.example.com 这种面板在 Access → Applications 里设成「需要登录(邮箱/Google/GitHub 等 SSO)才能访问」,否则等于把 NAS 管理口直接摊在公网。
  2. 最小暴露:只暴露必要的子域名,不要图省事把所有端口都挂出去。
  3. 强密码 + 2FA:源站服务本身也要强认证。
  4. 审计日志:Zero Trust 有访问日志,定期看一眼有没有异常。

十二、避坑要点总结(重点收藏)

  1. 🇨🇳 国内访问慢/不稳——头号坑:Cloudflare 在国内没有优质节点,访客在国内时延迟高、偶尔抽风。主要给海外或自己境外访问用;国内为主请回到上篇的 EdgeOne/阿里云方案。
  2. 只能原生代理 HTTP/HTTPS:SSH/RDP/TCP 需要 Cloudflare Access + 客户端 cloudflared / WARP,不能直接浏览器开。
  3. UDP 完全不支持:WireGuard、UDP 游戏服等走不了 Tunnel,别浪费时间。
  4. 域名必须托管到 Cloudflare:DNS 不在 CF 管,Tunnel 建不起来(它要自动写 CNAME)。
  5. 隧道是出站的,但 cloudflared 必须常开:它断线公网就访问不了;务必配 --restart=always 或系统服务自启,并关注离线告警。
  6. ingress 顺序 + 兜底规则:规则从上往下匹配,最后一定要放 http_status:404 兜底,否则未匹配请求报错。
  7. 免费额度和公平使用:Tunnel 本身免费,但别拿它当无限制 CDN / 下载站滥用,触发公平使用限制会被限流。
  8. 源站证书问题service: https://localhost:端口 时若源站是自签证书,记得加 originRequest.noTLSVerify: true,否则握手失败。
  9. 凭据文件别泄露cert.pem<uuid>.json 等于你隧道的钥匙,泄露了别人能劫持你的隧道。
  10. 多服务用不同子域名:一个隧道可以挂很多 Public Hostname,按需加就行,不用建多个隧道。
  11. 改配置要重启 tunnel:修改 config.yml 后需重启 cloudflared 进程才生效。
  12. 别把管理后台裸奔:见第十一节,一定要套 Cloudflare Access 鉴权。

十三、常见问题 FAQ

Q:访问提示 1033 / 隧道连不上? A:排查顺序——① cloudflared tunnel list 看隧道是否 HEALTHY;② 容器/进程是否在跑;③ config.ymlservice 地址本地能否 curl 通(localhost:端口);④ ingress 是否漏了兜底规则;⑤ DNS 是否真正生效(dig drive.example.com 看是否指向 *.cfargotunnel.com)。

Q:国内访问很慢/打不开怎么办? A:这是 Cloudflare 国内线路问题,不是你配置错。两个思路:① 海外/自用为主就忍;② 国内为主改用上篇 EdgeOne/阿里云 CDN(需备案)。也可以给国内访客单独用 WARP 客户端(但 WARP 在国内同样不稳)。

Q:能穿透 UDP 游戏服务器 / WireGuard 吗? A:不能。Cloudflare Tunnel 不支持 UDP。UDP 需求请考虑:有公网 IP 的云服务器做中转、或 Tailscale/ZeroTier 这类 P2P 组网。

Q:SSH 怎么弄最省事? A:在 Access 里开 Browser SSH,访客用浏览器就能登,无需本地装客户端,也最安全。

Q:和 frp / Ngrok / ZeroTier 比有什么区别? A:frp 需要你自备一台有公网 IP 的服务器;Ngrok 免费版随机域名且限流;ZeroTier/Tailscale 是 P2P 组网(适合「设备互联」而非「对外提供 Web 服务」);Cloudflare Tunnel 胜在免费、无需自备服务器、自带 HTTPS 与防护,但依赖 CF 网络(国内慢)。

Q:速度受什么限制? A:链路是「本地上行 → Cloudflare 边缘 → 访客」,所以① 受你家宽上行带宽限制;② 受 Cloudflare 节点到访客的链路限制(国内访客尤其明显)。

Q:免费版够用吗? A:个人使用完全够。Tunnel、Access(基础)、DNS、证书都是免费的。


十四、结语

Cloudflare Tunnel 是解决「无公网 IP、不想备案、想免费穿透」的最短路径:装个 cloudflared、建隧道、加公网主机名,三步搞定,家宽一个端口都不用开,源站 IP 还藏得严严实实。

它的天花板也很清楚——国内访问体验一般、不支持 UDP、非 HTTP 要配 Access。所以把它和上一篇的 EdgeOne/阿里云方案对照着看最合适:

  • 有 IPv6 / 已备案 / 主要给国内访问 → 上篇 EdgeOne + CDN 双栈方案;
  • 无公网 IP / 不想备案 / 海外或自用为主 → 本篇 Cloudflare Tunnel。

两篇都吃透,你家 NAS 的出网姿势就基本全了 😄


本文基于 Cloudflared + Cloudflare Zero Trust 的实践整理,控制台路径与免费额度以 Cloudflare 最新版本为准。