中文 English

域名买完别只会解析:用 Cloudflare Tunnel 把内网服务变成公网 HTTPS

发布时间: 2026-05-21
Cloudflare Tunnel HTTPS 内网穿透 域名 家庭实验室 Zero Trust speedtest

先说结论

前两篇已经讲了两件事:先用低成本 .xyz 域名把个人实验室的入口成本压下来,再把域名交给 Cloudflare 做 NS、DNS、DDNS、邮箱转发和基础自动化。本文继续往下走,讲“域名玩法 5”:用 Cloudflare Tunnel 把家里、NAS、虚拟机、Docker 容器里的 Web 服务发布成公网 https:// 地址。重点是:外部访问走 443 HTTPS,家里路由器不需要开 80/443 端口,也不需要把源站公网 IP 暴露出去

如果你前面已经买好了便宜域名,并且域名 NS 已经切到 Cloudflare,那么 Tunnel 就是非常值得继续折腾的一步。它能把 http://localhost:8080http://192.0.2.10:5000 这类内网服务,变成 https://nas.speedtest.example.xyz 这样的公网入口。

本文是这两篇文章的后续:

  1. 《80 块买十年:个人建站域名,为什么我会优先看 6 位数字 .xyz》
    原文地址:https://mp.weixin.qq.com/s/tbefnWGFI0QBFlRVcYjVEw
  2. 《80元十年域名别浪费:交给 Cloudflare 才算真正用起来》
    原文地址:https://mp.weixin.qq.com/s/h0o-vtGB_zj1aptaumBztQ

前文已经讲了便宜 .xyz 域名、Cloudflare NS、DNS、DDNS、企业邮箱这些基础配置。本文不再重复“怎么把域名接入 Cloudflare”,而是假设你已经有一个在 Cloudflare 托管的域名,然后继续讲:如何用 Cloudflare Tunnel 给内网服务开一个公网 HTTPS 入口。

本文所有示例都使用 example.xyznas.speedtest.example.xyz192.0.2.10localhost<TUNNEL_TOKEN> 这类文档占位符,不包含真实域名、真实账号、真实 Token、真实 Zone ID、真实内网地址或任何私有信息。你照着做时,把占位符替换成自己的域名和服务地址即可。

Cloudflare 官方 How it works 架构图

图 1:Cloudflare 官方文档中的 “How it works” 架构图。公网请求先到 Cloudflare,再通过 cloudflared 建立的出站隧道回到你的 origin。图片来源:Cloudflare Docs。

Cloudflare Tunnel 总览

图 2:Cloudflare Tunnel 的核心思路:公网用户访问 Cloudflare 的 443 HTTPS,内网 cloudflared 主动向 Cloudflare 建立连接,再把请求转给本地服务。

1. Cloudflare Tunnel 的关键价值:无需公网 IP

Cloudflare Tunnel 的关键价值,是让你在没有公网 IP、不能端口转发,或者不想暴露源站 IP 的情况下,仍然可以把内网 Web 服务发布成公网 HTTPS 地址。它仍然需要一个已经接入 Cloudflare 的域名,但不要求你的家庭宽带、NAS 或内网服务器拥有固定公网 IP。

这类场景可以理解成:

需要:一个已经接入 Cloudflare 的域名
不需要:家里有固定公网 IPv4
不需要:在路由器上转发 80 / 443 端口
不需要:把 NAS / 面板 / 虚拟机源站 IP 暴露给所有人

这点非常关键。传统做法通常是这样:域名 A 记录指向公网 IP,路由器把 443 转发到内网反代,反代再转到 NAS 或应用。这个方案能用,但前提很多:你要有公网 IP;运营商不能封入站端口;路由器转发规则要正确;证书续期要处理;源站 IP 可能被扫;家宽 IP 变化时还要 DDNS。

Tunnel 的路线不同。它让内网机器主动跑一个 cloudflared 连接器。这个连接器从内网主动连到 Cloudflare,不要求公网主动连进你家。用户访问 https://nas.speedtest.example.xyz 时,请求先到 Cloudflare 边缘网络,再通过这条隧道送到内网服务。对外看,用户访问的是 Cloudflare 提供的标准 HTTPS 入口;对内看,本地服务仍然可以只监听 localhost 或内网地址。

这就是为什么它特别适合个人实验室、NAS、Home Assistant、Uptime Kuma、内测 Web 面板、临时 Demo、Webhook 回调、开发环境预览等场景。你不需要为了一个小服务折腾公网 IP,也不需要在路由器上打开一堆入站端口。

2. Cloudflare Tunnel 到底是什么

Cloudflare 官方文档的定义很直接:Cloudflare Tunnel 通过一个轻量级 daemon,也就是 cloudflared,把你的基础设施连接到 Cloudflare。你创建一个 tunnel,安装并运行 cloudflared,然后把一个公网 hostname 映射到本地 service URL,例如把 app.example.com 映射到 http://localhost:8080

它的工作链路可以简单理解成四段。第一段,用户访问你的公网域名,例如 https://nas.speedtest.example.xyz,DNS 和 HTTPS 入口都在 Cloudflare 侧处理。第二段,Cloudflare 根据 Public Hostname 规则找到对应的 Tunnel。第三段,内网里的 cloudflared 已经提前主动连出到 Cloudflare,并维持多条长期连接,所以 Cloudflare 不需要从公网反向打进你家路由器。第四段,cloudflared 收到请求后,再把它转发给本机或内网里的真实服务,例如 http://localhost:8080http://192.0.2.10:5000

所以 Tunnel 的关键不是“Cloudflare 直接访问你的内网 IP”,而是“内网 connector 先主动连到 Cloudflare,公网请求再沿着这条已建立的连接回到 origin”。这也是它不需要路由器端口转发、不需要固定公网 IP 的根本原因。

翻译成更接地气的话:

  1. cloudflared 是装在你内网机器上的小客户端。
  2. 它主动连到 Cloudflare,不需要别人从公网直连你家。
  3. Cloudflare 负责接收公网 HTTPS 请求和证书。
  4. 你在 Cloudflare 上配置“哪个子域名转到哪个本地服务”。
  5. 一个 Tunnel 可以挂多个 Public Hostname,不必一个服务建一个 Tunnel。

它像反向代理,但反代入口不在你家路由器上,而在 Cloudflare 网络上;它像内网穿透,但它和 DNS、HTTPS、Cloudflare 账号、Zero Trust 控制面深度集成。对于个人用户,最舒服的地方在于配置路径比较统一:域名、DNS、证书、Public Hostname、Tunnel 状态都在 Cloudflare Dashboard 里能看到。

当然,Tunnel 不是银弹。它主要适合 HTTP/HTTPS Web 服务。Cloudflare 文档也说明,非 HTTP 服务例如 SSH、TCP、RDP 等需要客户端侧也运行 cloudflared 或使用对应的 Access 方式。本文只讲最常见、最容易落地的公网 HTTPS Web 访问。

3. 什么时候应该用 Tunnel,什么时候不该用

我建议先按场景判断,不要因为它免费就什么都往上挂。

适合用 Tunnel 的场景:

  1. 家里没有公网 IPv4,或者公网 IPv4 经常变化。
  2. 路由器不能或不想做 80/443 端口转发。
  3. 只想发布 Web 服务,例如 NAS Web、相册、监控、内部工具、临时 Demo。
  4. 想让外部地址天然是 https://,并由 Cloudflare 负责边缘证书。
  5. 想隐藏源站 IP,减少直接扫描和爆破。
  6. 想把多个内网 Web 服务放到同一个域名体系下管理。

不建议直接用 Tunnel 裸发布的场景:

  1. 数据库、Redis、管理 SSH、路由器后台这类高风险服务。
  2. 没有登录、没有权限、没有审计的内部系统。
  3. 上传下载量巨大、对延迟和吞吐非常敏感的服务。
  4. 违反 Cloudflare 服务条款或明显不适合走 HTTP 代理的用途。
  5. 你完全不理解被发布服务的安全边界,只是想“先暴露出去试试”。

要记住一句话:Tunnel 解决的是入口,不解决应用安全。它能让一个服务更容易被公网访问,也意味着这个服务更容易被公网所有人访问。如果是 NAS、面板、监控、相册、文件管理器,建议至少加上强密码、二次验证、访问控制,进一步可以配 Cloudflare Access,让登录 Cloudflare / Google / GitHub / 邮箱 OTP 后才能进入。

安全边界示意

图 3:Tunnel 让公网 HTTPS 入口变简单,但不替代认证、授权、审计和备份。

4. 准备工作:先把基础条件检查完

开始之前,建议先确认五件事。

第一,你的域名已经接入 Cloudflare,并且状态是 Active。也就是说,域名的 NS 已经从注册商切到 Cloudflare。前一篇已经讲过这个过程,这里不重复。你可以用:

dig NS example.xyz +short

看到 Cloudflare 分配的 nameserver,基本就说明权威 DNS 已经交给 Cloudflare。

第二,你要发布的服务在内网机器上本来就能访问。例如:

curl -I http://localhost:8080
curl -I http://192.0.2.10:5000

如果本地都打不开,不要先怪 Tunnel。先把应用本身跑起来。

第三,运行 cloudflared 的机器能访问外网。Cloudflare 官方文档提示,如果服务器在限制严格的防火墙后面,要确认它能连接 Cloudflare Tunnel 需要的端口。普通家宽、普通 VPS、普通 NAS Docker 环境一般没问题,但公司网络、校园网、受限机房可能需要额外放行。

第四,想好子域名命名。本文推荐延续前文的 speedtest 子域名思路,例如:

nas.speedtest.example.xyz
photo.speedtest.example.xyz
status.speedtest.example.xyz
ha.speedtest.example.xyz

其中真正想借用的标签是 speedtest,不是 URL path。也就是说,推荐 nas.speedtest.example.xyz,不推荐只写成 example.xyz/speedtest/nas。前文已经解释过原因:hostname / SNI 更早暴露给链路策略,而 path 往往在 HTTPS 之后才出现。

第五,准备好密钥管理方式。Cloudflare Dashboard 创建 Tunnel 时会给你一个 connector token。这个 token 等价于“允许某台机器接入这个 Tunnel”。不要截图发群,不要写进文章,不要提交到 Git,不要硬编码在公开脚本里。Docker Compose 可以放 .env 或 secret;systemd 可以使用 Cloudflare 生成的 service install 命令;长期维护时建议把 token 当密码对待。

5. 推荐路线:用 Cloudflare Dashboard 创建远程管理 Tunnel

Cloudflare Tunnel 有两种常见管理方式:Dashboard 远程管理和 CLI 本地管理。CLI 本地管理适合喜欢配置文件、希望把 ingress 规则放到 GitOps 流程里的人;Dashboard 远程管理更适合大多数个人用户,因为它少一步本地配置文件维护,创建 Public Hostname 也更直观。

本文推荐先用 Dashboard 路线。步骤大概是:

  1. 登录 Cloudflare Dashboard。
  2. 进入 Zero Trust。
  3. 进入 Networks / Tunnels。
  4. 创建 Tunnel。
  5. 选择运行环境,复制安装命令。
  6. 在内网机器运行 cloudflared
  7. Dashboard 看到 Tunnel 变 Healthy。
  8. 添加 Public Hostname,把子域名映射到本地服务。
  9. 浏览器访问 https://子域名 验证。

这条路线的好处是,每一步都有状态反馈。哪里没通,基本也能分层判断:是 connector 没连上,还是 Public Hostname 没建,还是 DNS 没生效,还是本地 service URL 写错。

创建 Tunnel 示意

图 4:在 Zero Trust 的 Tunnels 页面创建 Tunnel,命名可以用 home-lab-web 这类不包含隐私的名字。

6. 第一步:创建 Tunnel

打开 Cloudflare Dashboard 后,进入 Zero Trust 控制台。现在 Cloudflare 的菜单可能会随时间调整,但大体路径是:

Zero Trust -> Networks -> Tunnels -> Create Tunnel

创建时建议名字简单一点,例如:

home-lab-web
nas-tunnel
personal-services

不要把真实家庭地址、真实设备名、真实内网结构写进 Tunnel 名称。这个名字主要给自己看,能识别用途即可。

创建完成后,Cloudflare 会让你选择 connector 运行环境,比如 Linux、Docker、macOS、Windows。你选中对应环境后,页面会展示安装和运行命令,其中包含一个很长的 token。这个 token 只显示给你用于安装 connector,文章里必须写成 <TUNNEL_TOKEN>

如果你只是想最快跑通,可以用页面给出的命令;如果你已经有 Docker 环境,我更推荐 Docker Compose,因为后续更新、重启、迁移都清楚。

7. 第二步:安装并启动 cloudflared

Cloudflare 官方下载页提供了多种安装方式:Linux 可以用 Cloudflare 包仓库或直接下载二进制 / deb / rpm;macOS 可以用 Homebrew;Windows 可以用 winget;Docker 则有官方镜像。你不用背命令,Dashboard 里也会根据你选择的系统给出一条可复制命令。

7.1 Linux systemd 方式

如果你的服务跑在一台 Linux 机器上,最直接的方式是让 cloudflared 作为 systemd 服务运行。Dashboard 远程管理 Tunnel 时,常见命令类似:

sudo cloudflared service install <TUNNEL_TOKEN>
sudo systemctl status cloudflared

如果服务正常,你应该能看到 cloudflared.service 处于 running 状态。还可以看日志:

journalctl -u cloudflared -f

看到 connector 注册、连接建立、没有持续报错,说明这一层基本没问题。

7.2 Docker 方式

如果你本来就用 Docker 管理家庭服务,可以写成 docker-compose.yml

services:
  cloudflared:
    image: cloudflare/cloudflared:latest
    container_name: cloudflared
    restart: unless-stopped
    command: tunnel --no-autoupdate run --token ${TUNNEL_TOKEN}
    environment:
      - TZ=Asia/Shanghai

再配一个 .env

TUNNEL_TOKEN=<TUNNEL_TOKEN>

启动:

docker compose up -d
docker logs -f cloudflared

这里有两个细节。第一,.env 不要提交到公开 Git 仓库。第二,cloudflared 容器要能访问你要转发的服务。如果目标服务和 cloudflared 在同一个 compose 网络里,可以直接用服务名;如果目标服务在宿主机上,可能要用宿主机地址或 Docker 的 host gateway 配置。新手先用 http://host.docker.internal:8080 或宿主机局域网地址测试,确认通了再整理成更干净的网络结构。

安装 cloudflared 示意

图 5:Linux systemd 和 Docker 都能长期运行 cloudflared。核心是 token 不要泄露,服务要能自动重启。

8. 第三步:看到 Tunnel 变 Healthy

启动 cloudflared 后,回到 Cloudflare Dashboard 的 Tunnel 页面。正常情况下,Tunnel 状态会从未连接变成 Healthy。这个状态非常重要,因为它说明内网 connector 已经成功连到 Cloudflare。

如果这里不 Healthy,不要急着配置子域名,先排查 connector:

  1. token 是否复制完整;
  2. 系统时间是否正常;
  3. 机器是否能访问外网;
  4. Docker 容器是否反复重启;
  5. systemd 日志里是否出现认证或网络错误;
  6. 防火墙是否阻止了 cloudflared 出站连接。

只有 Tunnel Healthy 以后,Public Hostname 才有意义。否则你即使把 DNS 配好了,用户访问时也会遇到 1016、1033、502 之类错误。

9. 第四步:添加 Public Hostname

进入刚创建的 Tunnel,选择添加 route 或 Public Hostname。这里是整篇文章最关键的配置。

以 NAS Web 面板为例,假设内网服务运行在同一台机器的 8080 端口:

Subdomain: nas.speedtest
Domain: example.xyz
Path: 留空
Service Type: HTTP
Service URL: http://localhost:8080

最终公网访问地址就是:

https://nas.speedtest.example.xyz

如果服务在另一台内网机器上,例如 192.0.2.10:5000,可以写:

Service URL: http://192.0.2.10:5000

如果内网服务本身是 HTTPS,例如 https://192.0.2.10:8443,也可以选择 HTTPS,但要注意证书校验。自签证书、证书域名不匹配、内网 IP 证书不受信任,都可能导致 Cloudflare 到 origin 这一段失败。新手为了先跑通,建议优先用内网 HTTP:外部用户到 Cloudflare 这一段仍然是 HTTPS,Cloudflare 到你内网服务这一段走 Tunnel 内部连接。等你理解清楚后,再考虑 origin HTTPS 和证书校验。

Public Hostname 配置示意

图 6:Public Hostname 的关键是把公网子域名映射到本地 Service URL。Cloudflare 会处理公网 443 HTTPS 入口。

Cloudflare 文档里也提到,当你通过 Dashboard 添加 route 时,Cloudflare 会自动创建 DNS 记录,把 hostname 指向 tunnel 的 <UUID>.cfargotunnel.com。如果你用 CLI 本地管理,也可以用 cloudflared tunnel route dns 来创建 CNAME。普通个人用户用 Dashboard 添加 route 最省心,因为 DNS 和 route 通常会一起处理。

10. 为什么我推荐 *.speedtest 子域名

前文讲 NAS 外网访问时,提到过一个经验技巧:把 speedtest 放到子域名里,有时能改善部分家庭宽带外网访问体验。这个技巧不是保证,不是协议标准,也不是加速魔法,但它验证成本低,命名也不难看,所以适合和 Tunnel 一起用。

我推荐的形式是:

nas.speedtest.example.xyz
photo.speedtest.example.xyz
status.speedtest.example.xyz
ha.speedtest.example.xyz

而不是:

example.xyz/speedtest/nas
example.xyz/speedtest/photo

原因仍然是 hostname / SNI 比 path 更早被链路看到。如果某些网络策略真的会参考域名标签,那么 speedtest 应该出现在主机名里,而不是藏在 HTTPS 请求路径里。

speedtest 子域名示意

图 7:推荐把 speedtest 放在 hostname 中。路径里的 speedtest 不能替代子域名标签。

如果你担心名字太长,可以只给外网访问量大的服务使用 speedtest

nas.speedtest.example.xyz      NAS / 文件 / 相册
video.speedtest.example.xyz    视频或媒体入口
status.example.xyz             轻量状态页,不一定需要 speedtest
admin.example.xyz              管理后台,最好不要公开裸访问

注意,这里说的是“推荐命名”,不是说加上 speedtest 就一定更快。最可靠的方法仍然是对照测试:同一个服务同时配置 nas.example.xyznas.speedtest.example.xyz,从同一网络、同一时间段访问同一资源,比较首屏、下载、视频预览、断流情况。如果没有差异,就不要神化它;如果差异明显,就把它作为优先入口保留。

11. 一个完整例子:把本地 Web 服务发布成 HTTPS

假设你家里有一个 Web 服务,内网可以这样访问:

curl -I http://localhost:8080

目标是让它公网可访问:

https://demo.speedtest.example.xyz

最小步骤如下:

  1. 在 Cloudflare Zero Trust 创建 Tunnel,命名 home-lab-web
  2. 选择 Linux 或 Docker,复制安装命令。
  3. 在运行服务的机器上启动 cloudflared
  4. Dashboard 确认 Tunnel 状态 Healthy。
  5. 添加 Public Hostname:
Subdomain: demo.speedtest
Domain: example.xyz
Service Type: HTTP
Service URL: http://localhost:8080
  1. 保存后访问:
curl -I https://demo.speedtest.example.xyz

如果返回 HTTP/2 200301302 或应用本身预期的状态码,说明公网 HTTPS 到本地服务的主链路已经通了。浏览器打开页面,再检查登录、静态资源、上传、WebSocket、反代路径等细节。

12. 如果你更喜欢本地配置文件:CLI 管理 Tunnel

Dashboard 路线适合上手,但也有人喜欢把配置文件留在本地,方便备份和版本管理。Cloudflare 的本地管理大致流程是:

cloudflared tunnel login
cloudflared tunnel create home-lab-web
cloudflared tunnel list

然后创建 ~/.cloudflared/config.yml

tunnel: <Tunnel-UUID>
credentials-file: /root/.cloudflared/<Tunnel-UUID>.json

ingress:
  - hostname: demo.speedtest.example.xyz
    service: http://localhost:8080
  - hostname: nas.speedtest.example.xyz
    service: http://192.0.2.10:5000
  - service: http_status:404

创建 DNS 路由:

cloudflared tunnel route dns home-lab-web demo.speedtest.example.xyz
cloudflared tunnel route dns home-lab-web nas.speedtest.example.xyz

运行:

cloudflared tunnel run home-lab-web

长期运行可以安装成服务:

cloudflared service install
systemctl start cloudflared
systemctl status cloudflared

CLI 方式的优点是配置清楚、可复制、适合多 hostname;缺点是对新手来说更容易在 cert.pem、credentials file、config path、systemd 用户目录这些细节上踩坑。比如官方文档特别提醒,使用 sudo 安装服务时 $HOME 可能变成 /root,导致它找不到你在普通用户目录里创建的配置文件。这种情况下要显式指定 config 路径。

13. Tunnel Token、Tunnel ID 和 DNS CNAME 不要混淆

这里非常容易混。

Tunnel Token 是给 connector 用的,通常是一长串敏感字符串。它让 cloudflared 能接入你的 Tunnel。泄露后别人可能伪装成你的 connector,所以必须保护。

Tunnel ID 是 Tunnel 的 UUID。Cloudflare 会生成 <UUID>.cfargotunnel.com 这样的目标。DNS CNAME 会指向它。UUID 本身没有 token 那么敏感,但也没必要公开到处贴。

DNS CNAME 是把你的公网 hostname 指向 tunnel 子域名,例如:

CNAME demo.speedtest.example.xyz -> <UUID>.cfargotunnel.com

Cloudflare 文档说明,cfargotunnel.com 子域名只会代理同一个 Cloudflare 账号里的 DNS 记录。也就是说,别人即使知道你的 Tunnel UUID,也不能在另一个账号里随便建一条 CNAME 来蹭你的 Tunnel。但这不代表 token 可以泄露;token 和 connector 权限仍然要按密钥处理。

Tunnel Token 与 DNS CNAME 关系

图 8:Token 给 connector,Tunnel ID 用于 CNAME,Public Hostname 负责把公网域名映射到本地服务。

14. 验证方法:从服务、Tunnel、DNS、HTTPS 四层看

不要只看浏览器能不能打开。排障时建议按层检查。

第一层,本地服务是否正常:

curl -I http://localhost:8080

第二层,cloudflared 是否正常:

systemctl status cloudflared
journalctl -u cloudflared -n 100 --no-pager

或者 Docker:

docker ps
docker logs --tail=100 cloudflared

第三层,Cloudflare Dashboard 里 Tunnel 是否 Healthy,Public Hostname 是否存在,Service URL 是否写对。

第四层,DNS 是否正确:

dig CNAME demo.speedtest.example.xyz +short

应该能看到类似:

<TUNNEL-UUID>.cfargotunnel.com.

第五层,公网 HTTPS 是否正常:

curl -I https://demo.speedtest.example.xyz

如果浏览器打不开但 curl -I 有响应,要继续看应用层跳转、Cookie、反代路径、WebSocket、上传大小限制等问题。

验证清单

图 9:上线前后按层验证,不要只凭浏览器感觉。

常见错误可以这样理解:

  1. 1016:DNS 指到了 Tunnel,但 Cloudflare 找不到可用 origin。常见原因是 Tunnel 没运行或 DNS / route 不匹配。
  2. 502 / 1033:connector 可能通了,但本地 Service URL 不可达、协议写错、端口错、应用崩了。
  3. 证书错误:通常发生在你把 origin service 写成 HTTPS,但内网证书不被信任或域名不匹配。
  4. 页面能开但资源 404:应用自己生成的外部 URL、base path、反代前缀有问题。
  5. 登录循环:Cookie domain、SameSite、HTTPS detection、反代 header 可能没处理好。

15. 是否还需要 Nginx、Caddy、Lucky 这类反向代理

不一定。

如果你的内网只有一个服务,Tunnel 可以直接指向它:

demo.speedtest.example.xyz -> http://localhost:8080

但如果你已经有 Nginx、Caddy、Lucky、Traefik 这类内网反代,仍然可以保留:

Cloudflare Tunnel -> Caddy / Nginx -> NAS / App / Dashboard

这样做的好处是,本地路由和证书策略仍然集中管理;坏处是链路多一层,排障时要多看一层日志。新手可以先让 Tunnel 直接指向目标服务,等跑通后再接入内网反代。

如果你用 Caddy 或 Nginx,注意保留 Host header。很多应用需要知道外部访问域名,尤其是生成回调 URL、OAuth 登录、WebSocket、反向代理路径时。如果 Host 被改成内网 IP,应用可能会跳回错误地址。

16. 安全建议:公网 HTTPS 不等于可以公开裸奔

Tunnel 很容易让人产生错觉:既然不用开端口、源站 IP 也藏起来了,那是不是就安全了?不是。

它只是让入口更好管,不代表应用没有漏洞。公网能访问的东西就会被扫。哪怕源站 IP 没暴露,域名本身也可以被发现,路径也可能被猜,弱密码也会被撞。

建议至少做到:

  1. 所有后台类服务都设置强密码和二次验证。
  2. 不要把路由器、PVE、ESXi、数据库、Redis 这类高风险入口直接做 Public Hostname。
  3. NAS 文件管理、相册、监控面板最好加 Cloudflare Access。
  4. 对外只发布必要路径,不要把整个内网反代树一把梭公开。
  5. 定期更新应用、NAS、Docker 镜像和 cloudflared
  6. Token 泄露时立即删除 connector 或 rotate token。
  7. 重要数据仍然要备份,Tunnel 不承担备份职责。

如果你只是给自己用,Cloudflare Access 很值得加。它可以要求访问者先通过邮箱 OTP、Google、GitHub、OIDC 等方式认证。这样即使应用本身登录页比较弱,也能在前面再加一道门。

17. 和 DDNS、端口转发、FRP 相比,它解决了什么

DDNS 解决的是“公网 IP 会变”的问题。你仍然需要公网 IP,仍然要开端口,仍然要处理源站暴露。

路由器端口转发解决的是“公网请求怎么进内网”的问题。它简单直接,但暴露面大,遇到没有公网 IP 或运营商限制就没办法。

FRP、NPS、ZeroTier、Tailscale 这类方案各有用途。FRP 更像自建穿透,需要一台有公网入口的服务器;Tailscale 更适合组网和私有访问,不一定适合直接给普通公网用户访问一个标准 HTTPS 域名。

Cloudflare Tunnel 的优势在于,它把“域名、证书、公网 443、穿透、边缘防护、访问控制”放在同一套体系里。对已经把域名接到 Cloudflare 的个人用户来说,学习成本很低,成本也低。

它的代价是你依赖 Cloudflare 网络;访问体验受 Cloudflare 路径影响;某些大流量或特殊协议并不适合;对国内网络来说,不同地区体验可能差异明显。所以最务实的做法是:把它作为个人实验室的一个标准入口方案,但保留备用路径,不要把所有服务都无脑绑死在一个外部平台上。

18. 我自己的推荐落地顺序

如果你是第一次做,我建议按这个顺序来:

  1. 先选一个无关紧要的 Web 服务,例如 Uptime Kuma、静态页面、测试容器。
  2. 用 Dashboard 创建一个 Tunnel。
  3. 用 Docker 或 systemd 跑起 cloudflared
  4. 添加 demo.speedtest.example.xyz 这样的 Public Hostname。
  5. curl -I 和浏览器确认能访问。
  6. 再接入 NAS、相册、Home Assistant 这类更有价值的服务。
  7. 对后台类服务加 Cloudflare Access。
  8. 保留一个普通子域名和一个 speedtest 子域名做对照测试。
  9. 整理命名规范和备份 token 管理方式。
  10. 定期检查 Tunnel 状态、访问日志和应用更新。

不要一上来就把所有家庭服务都发布出去。Tunnel 很方便,方便也意味着误操作成本低。越容易发布,越要克制。

19. 一个可以直接照抄的命名模板

假设你的域名是 example.xyz,可以这样规划:

status.example.xyz              公开状态页
blog.example.xyz                静态博客或公开页面
demo.speedtest.example.xyz      临时 Demo
nas.speedtest.example.xyz       NAS Web 入口,建议加 Access
photo.speedtest.example.xyz     相册入口,建议加 Access
ha.speedtest.example.xyz        Home Assistant,建议加 Access
admin.example.xyz               不建议裸公开,最好只走私有网络或 Access

如果你要做对照测试,可以同时保留:

nas.example.xyz
nas.speedtest.example.xyz

两个 hostname 都指向同一个 Tunnel 和同一个 Service URL,然后在同一网络下测试。这样你能知道 speedtest 命名到底有没有实际帮助,而不是靠玄学判断。

20. 总结:80 元十年域名真正开始好玩,是从 Tunnel 开始的

前两篇讲的是“买一个够便宜、够稳定、够长期的个人实验室域名”,以及“把这个域名交给 Cloudflare 管起来”。那两步完成后,域名已经不是一个空壳:它有 DNS,有 DDNS,有邮箱入口,有 API 自动化能力。

而 Cloudflare Tunnel 让这个域名继续往前走了一步:它不只是解析到某个 IP,而是可以把你家里的 Web 服务安全地接到公网 HTTPS 入口上。你不用申请固定公网 IP,不用在路由器上开 443,不用把源站直接暴露给扫描器,也不用为了一个小服务单独买云服务器。

最小可用方案其实很简单:

Cloudflare 托管域名
+ 一个 Tunnel
+ 一个 cloudflared connector
+ 一个 Public Hostname
+ 一个本地 Web 服务
= 一个可公网访问的 HTTPS 地址

如果再结合 nas.speedtest.example.xyz 这类命名,你还可以顺手做网络路径对照测试,看看前文提到的 speedtest 子域名经验是否对你的线路有帮助。

最后再强调一次:Tunnel 让入口变简单,不代表安全可以省略。把服务发布出去之前,先想清楚它是否应该被公网访问;如果应该访问,就加认证、加 Access、加日志、加备份。这样,一个 80 元十年的 .xyz 域名,才算真的被你用出了价值。

来源与参考

  1. Cloudflare Tunnel 官方文档:https://developers.cloudflare.com/tunnel/
  2. Cloudflare Tunnel Setup:https://developers.cloudflare.com/tunnel/setup/
  3. Cloudflare Tunnel Routing:https://developers.cloudflare.com/tunnel/routing/
  4. cloudflared Downloads:https://developers.cloudflare.com/tunnel/downloads/
  5. Cloudflare Tunnel 本地管理与 Linux service:https://developers.cloudflare.com/tunnel/advanced/local-management/create-local-tunnel/https://developers.cloudflare.com/tunnel/advanced/local-management/as-a-service/linux/
  6. 前文《80 块买十年:个人建站域名,为什么我会优先看 6 位数字 .xyz》:https://mp.weixin.qq.com/s/tbefnWGFI0QBFlRVcYjVEw
  7. 前文《80元十年域名别浪费:交给 Cloudflare 才算真正用起来》:https://mp.weixin.qq.com/s/h0o-vtGB_zj1aptaumBztQ
  8. 前文 speedtest 子域名讨论:https://mp.weixin.qq.com/s/7Jz6us_o2TafY9TovlwOPA