news 2026/9/27 23:30:37

Cloudflare Zero Trust内网穿透:无需公网IP安全访问NAS

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Cloudflare Zero Trust内网穿透:无需公网IP安全访问NAS

近一年的时间,我都在用一种方式管理家里那台NAS:所有跑在卧室角落小主机上的服务,不用开放任何路由器端口、不需要运营商分配公网IP,甚至不用租一台云服务器,只需要一个已经在 Cloudflare 托管的域名,加上 Cloudflare Zero Trust 的内网穿透能力,就能把本地的 Web 服务安全地暴露到固定子域名上。这篇文章就是一次完整记录,包含实际配置步骤和踩过的坑,适合没有公网IP、不想花钱买服务器、又想在外面访问家里服务的朋友照着操作,我会尽量用复制粘贴级别的傻瓜式说明。

提示:本文方案基于 Cloudflare 官方 Zero Trust / Cloudflared Tunnel 实现,全程不需要修改路由器配置,也不依赖运营商提供公网 IPv4。免费套餐足够个人使用,前提是有一个域名,并且把域名的 DNS 托管到 Cloudflare。

1. 为什么最终选了 Cloudflare Zero Trust:与其他内网穿透方案的真实对比

我在没有公网IP这件事上吃过不少亏。早期试过在路由器上做端口映射,确实能通,但问题很明显:服务一开,日志里全是陌生IP的扫描和爆破尝试,连续几天后我直接把规则删了。后来用过 frp,需要一台有公网IP的服务器做中转,当时为了省钱买了一台1M小水管,实际体验是传输速度被卡得死死的,服务器续费提醒还每个月准时来。再后来试过 ngrok,免费版每次启动给的临时域名不固定,用起来总有那么点不顺手。

最后让我定下来的,是 Cloudflare Zero Trust 里的 Tunnel 功能。它和我之前用的方案有一个本质区别:不需要在公网侧开任何入站端口,而是由本地机器主动向外建立一条长连接,Cloudflare 边缘节点再把访问请求沿着这条连接送回来。用一句话说,它把“让外人进来”变成了“我自己出去站岗”。这个思路在家庭网络、临时开发环境、没有固定公网IP的办公网环境下都非常实用。

我把几个主流方案的真实体验整理成了一张表,方便快速判断:

方案是否需要公网IP是否需要额外服务器是否需要域名访问控制个人免费体验
frp需要需要可选自己实现工具免费,但服务器要花钱
ngrok不需要不需要免费版用临时域名带简单密码临时域名每次变化,有限制
Cloudflare Tunnel不需要不需要必须托管在Cloudflare内置Access认证隧道和流量在个人场景下够用

1.1 核心优势:零公网IP、零服务器、零入站端口

Cloudflare Tunnel 最核心的价值,是它把“内网穿透”这件事从网络层上升到了身份层。传统端口映射需要你告诉路由器“来自公网的某些请求,请转给内网某个IP”,这等于在防火墙墙上开了一个洞。而 Tunnel 的做法是让本地服务主动连接到 Cloudflare,外部用户访问你的域名时,Cloudflare 再把请求通过这条已经建立的连接传回本地。

整个过程本地只需要能访问公网出站流量就行,443 端口能连通就没问题。对家庭宽带来说,这意味着我不需要打电话去要公网IP,不需要买云服务器,也不需要忍受端口扫描。即使是完全没有公网IPv4的环境,只要家里路由器能正常上网,隧道就能正常工作。对于临时在咖啡厅、酒店、手机热点下调试代码的人来说,这也非常方便。

1.2 Cloudflare Access 等于白送了一道认证大门

很多隧道工具只管通,不管谁进。而 Cloudflare Zero Trust 本身就带一个 Access 模块,可以放在隧道域名前面做身份验证。打开之后,未认证用户访问你的服务会先看到一个登录页,只有通过邮箱验证码、邮箱域名限制、或者 IP 限制的人才能继续访问。

这点对我来说几乎是决定性优势。家里的 NAS 服务如果直接裸奔在公网域名上,被扫描器收录只是时间问题。但套上 Access 之后,别人连你的应用页面都看不到,看到的只是 Cloudflare 的验证页面,攻击面一下子小了很多。这个能力放在 ngrok、frp 上,通常还需要自己再做一层前置认证,配置复杂度完全不同。

1.3 什么人合适,什么人不合适

我自己的判断标准是:如果你是个人开发者,家里有 NAS 或者一台常开的小主机,想在外面访问照片、笔记、代码仓库、下载工具,或者是开发过程中需要临时把一个本地服务丢给合作方验证,那 Cloudflare Tunnel 是当前最省心的方案。

但如果你追求极低延迟、需要长期传输大量文件,或者已经有性能很好的国内云服务器,那 frp 这类方案可能仍然更适合。Cloudflare 边缘节点和家里之间的链路毕竟要过国际线路,交互控制类服务完全可用,但大文件传输的体验不一定比国内服务器中转好。工具选型没有绝对优劣,看清自己的需求再选就行。

2. 准备工作:域名、本地服务和 cloudflared 安装

在真正创建隧道之前,先把三样东西准备好:一个 Cloudflare 账号、一个托管在 Cloudflare 的域名、一个本地 Web 服务。这三样缺一不可,不过准备过程都不复杂,账号注册和域名托管都是常规操作页。

2.1 账号和域名:这一步绕不过去

Cloudflare Tunnel 要求使用自有域名,因为创建子域名后,Cloudflare 需要自动帮你写入一条 DNS 解析记录。之前没有接触过 Cloudflare 的朋友,可以按这个顺序操作:

  1. 打开 Cloudflare 官网注册账号,邮箱验证一下就能用。
  2. 登录后点击“添加站点”(Add a site),输入你的域名,选择 Free 免费套餐。
  3. 根据页面提示,去你的域名注册商后台,把域名 NS 记录改成 Cloudflare 给出的两个地址。
  4. 等 Cloudflare 提示域名状态变成“活跃”(Active),就可以继续。NS 切换生效时间从几分钟到几小时不等,我遇到过最久的一回等了约6小时,一般一小时内能好。

如果你的域名之前就已经托管在 Cloudflare,那就直接跳过这一步。有一点我想提醒:这里用的是免费套餐,不需要开通任何付费项目,Zero Trust 页面会提示试用付费版,但个人使用继续用 Free 即可,不需要绑定信用卡也能创建隧道。

2.2 先确认本地服务可以访问

隧道只是通道,通道那头必须有一个真正在运行的服务。无论你想暴露的是 Home Assistant、Jellyfin、自建密码库,还是随便一个本地调试用的 API,先确认同一台机器上能正常访问它。

比如在目标机器上执行:

curl http://127.0.0.1:8123 curl http://localhost:3000/api/health

如果本机访问不通,那隧道配好之后一定也是不通的,这是最容易被忽略的起点。这里还有一个细节:cloudflared 运行在哪台机器,它能访问到什么服务,隧道就只能转发什么服务。如果你的服务在 NAS 的 Docker 容器里,cloudflared 可以运行在宿主机上,也可以用 Docker 方式跑,但必须确认宿主机到容器的端口映射是通的。

2.3 安装 cloudflared:不同系统的三个命令

cloudflared 是 Cloudflare Tunnel 的客户端,也是整条隧道里唯一需要装在本地的组件。安装方式按系统来:

  • Linux(Debian/Ubuntu)可以通过官方脚本安装:
curl -L https://pkg.cloudflare.com/cloudflared-ascii-install.sh | bash

或者手动下载二进制文件:

wget -q https://pkg.cloudflare.com/cloudflared-linux-amd64 -O cloudflared chmod +x cloudflared sudo mv cloudflared /usr/local/bin/
  • macOS 直接用 Homebrew:
brew install cloudflared
  • Windows 去 Cloudflare 官网下载 cloudflared.exe,放在固定目录如C:\cloudflared,在 PowerShell 里切换到该目录执行命令。

装完之后统一验证:

cloudflared --version

能看到版本号就说明安装成功。这里分享一个经验:如果是在 Linux 服务器上装,尽量别用 root 用户日常操作,后面创建隧道时会在当前用户目录生成凭证文件,权限弄乱了会比较麻烦。

3. 最关键的几步:在 Zero Trust 面板里创建隧道并绑定域名

安装完成之后,大部分操作就是点鼠标加复制粘贴。写这篇整理时是 2026 年 4 月,面板界面可能跟你看的时候略有差异,但核心路径没有变,整体可以概括为三个动作:建隧道、装连接器、配置 Public Hostname。

3.1 进入 Zero Trust 面板创建隧道

登录 Cloudflare 控制台,在首页顶部找到 Zero Trust 入口。第一次进入时,会让你设置一个团队名称(Team Name),比如我填的是my-home,这个名称会成为后续访问认证页地址的一部分,随便起一个记得住就行。

然后按这个路径操作:

  1. 左侧菜单找到 Networks,进入 Tunnels 页面,点击 Create a tunnel。
  2. 选择隧道类型,选 Cloudflared,点击下一步。
  3. Cloudflare 会让你给隧道起名,比如home-nas,点击 Save tunnel。

起名之后页面会跳转到安装命令页。这里先解释一下这个隧道是什么:它本质上是一个持久的加密长连接,由你本地运行的 cloudflared 主动发起,保持与 Cloudflare 边缘节点的连接。隧道名称只是本地管理标识,可以随意起,后面还能改名。

3.2 安装连接器:一行命令完成连接

创建隧道后,页面会按你选择的操作系统显示安装命令。Windows 和 Linux 都适用下面这种格式:

cloudflared service install <token>

其中<token>是 Cloudflare 为这次隧道生成的专用连接令牌,复制整条命令,在你运行服务的那台机器上执行。执行后,cloudflared 会被安装成系统服务,自动开机自启,并在后台保持连接。

如果你只是临时测试,先不想装成系统服务,可以改成前台运行:

cloudflared tunnel run --token <token>

前台运行的好处是日志直接打在屏幕上,方便观察状态。当你看到类似Registered tunnel connection的日志,说明隧道已经连上了。此时回到 Cloudflare 面板的 Tunnels 页面,隧道状态会从待处理变成 Healthy。

这个小步骤是整篇配置里最容易出问题的地方。遇到隧道一直不 Healthy,最常见的两个原因:一是命令没复制完整,token 少了一段;二是本机防火墙拦截了 cloudflared 进程的出站连接。另外在 Windows 上如果执行命令时提示找不到 cloudflared,记得先切换到 exe 所在目录,或者把 exe 所在目录加到系统 PATH 环境变量里。

3.3 配置 Public Hostname:把子域名指到内网端口

隧道连上之后,要让外部访问真正到达本地服务,还需要配置 Public Hostname。具体步骤:

  1. 在 Tunnels 页面找到你的隧道,在右侧操作菜单里选择 Configure。
  2. 切换到 Public Hostname 标签页,点击 Add a public hostname。
  3. 填写三个关键项:
    • Subdomain:你想用的子域名前缀,例如nas
    • Domain:下拉框选择你托管在 Cloudflare 的域名
    • Service Type:HTTP 或 HTTPS,按本地服务类型选
    • URL:填写本地服务地址,例如localhost:8096或192.168.1.10:8123
  4. 点击 Save,保存配置。

保存后,Cloudflare 会自动在 DNS 里创建一条指向该隧道的 CNAME 记录,完全不需要你手动加解析。这也是“傻瓜操作”的关键点之一:如果是 CLI 方式,这条路要自己跑命令,但在面板里点几下就完成了。

配置完,浏览器访问https://nas.你的域名.com,如果能看到本地服务界面,说明整条链路已经通了。这里我建议把服务类型选成 HTTP,即使本地服务本身没有配置 HTTPS 也没关系,因为外部用户访问时 Cloudflare 会自动提供 HTTPS 加密,用户到 CF 这一段是安全的。

3.4 验证链路:看域名、看日志、看连接数量

验证不能只看页面打开就算完,我通常从三个角度确认:

  • 浏览器打开域名,确认服务功能正常,页面可以交互。
  • Cloudflare 面板 Tunnels 页面里,隧道状态显示 Healthy,Connector 列能看到至少一个连接。
  • 本地看 cloudflared 日志。前台运行的话直接看屏幕;如果是系统服务,Linux 执行journalctl -u cloudflared -f,macOS 用sudo log stream --predicate 'process == "cloudflared"',Windows 则在服务管理里查看状态。

如果域名打不开,先别急着怀疑隧道有问题,可能是 DNS 解析还没生效,也可能是本地服务刚好挂了。建议先用ping 你的域名看解析是否已经指向 Cloudflare,再回到本地用curl验证源站服务。

3.5 面板背后的 CLI 方式,了解一下有好处

如果你喜欢命令行,也可以完全用 CLI 创建隧道,面板操作本质上是把这些命令拼在一起:

cloudflared tunnel login cloudflared tunnel create home-nas cloudflared tunnel route dns home-nas nas.你的域名.com cloudflared tunnel run home-nas

第一条login会生成一张本地证书,用于确认账号身份。第二条create会创建隧道并生成 JSON 凭证文件。第三条route dns会在 Cloudflare 上创建 DNS 记录,把子域名指向隧道。第四条run前台运行隧道。面板操作帮我省去了手动记忆这些命令的麻烦,但理解了 CLI 之后,遇到面板配置异常时排查思路会清晰很多。

4. 没做这步等于裸奔:用 Cloudflare Access 给隧道加访问控制

隧道建好后,服务实际上已经出现在公网上了。如果只是临时调试,可能无所谓;但如果是 NAS、内部工具、数据库管理面板这类东西,强烈建议加上访问控制。Cloudflare Zero Trust 的 Access 模块可以在 Cloudflare 边缘做一道身份验证,未认证的请求会被直接挡在验证页面外面。

4.1 为什么要加:日志不会骗人

我刚开始配好隧道时,觉得自己域名冷门,应该没人发现,结果一天之后去看访问日志,已经有几十个陌生IP在尝试访问/login、/admin这些常见路径。域名只要出现在公网 DNS 记录里,就会被各种扫描器收录,这不是玩笑。

加上 Access 之后,未认证请求连你的应用都看不到。访问者会先被引导到 Cloudflare 的登录验证页,只有通过策略校验的人才能放行。这就相当于在大门外单独修了一个门卫亭,而不是把家里的门直接敞着。

4.2 添加 Access Application 的完整步骤

在 Zero Trust 左侧菜单里找到 Access,进入 Applications,操作如下:

  1. 点击 Add an application,类型选择 Self-hosted。
  2. Application domain 填写你的子域名,例如nas.你的域名.com;Application name 随意起一个。
  3. 点击下一步配置 Policy:
    • Policy name 随意,例如my-access
    • Action 选择 Allow
    • Include 选择 Emails,然后填入你的邮箱;如果你想允许某个域名下的所有邮箱,可以选 Email ending in 然后输入域名后缀。
    • 可选:再添加一个 IP 条件,只允许你自己常用的出口 IP 段通过。
  4. 保存后回到 Applications 列表,能看到一条新的应用规则。

这里有个细节:Policy 里可以配置多条 include 规则,例如“邮箱是我的邮箱,并且 IP 在常用范围”,两者都满足才会放行。规则按顺序执行,个人场景一般一条就够。

4.3 实际使用体验和几个注意事项

开启 Access 后,首次访问你的域名,浏览器会跳到<你的团队名>.cloudflareaccess.com,输入邮箱后 Cloudflare 会向该邮箱发送一封验证邮件,点击邮件里的链接即可完成验证。验证通过后,Cloudflare 会在浏览器种一个 cookie,之后一段时间内不需要反复登录,体验还算顺滑。

有几点要注意:

  • 如果服务是给手机 App 用的,App 内部浏览器可能不支持完整的验证流程,这种情况下要么临时关闭 Access,要么用 Service Token 方式。
  • Service Token 是给 API 和脚本场景用的认证方式。在 Access 菜单里找到 Service Auth,创建 Token 后,请求时带上CF-Access-Client-Id和CF-Access-Client-Secret两个请求头,就能跳过登录页。这个方案适合不想在脚本里处理邮件验证的场景。
  • 如果配置了多个子域名,每个子域名需要单独创建 Application;也可以创建一个覆盖*.你的域名.com的通配符应用,这样所有子域名都会套同一套认证策略。

4.4 免费版够用吗

Cloudflare Access 免费版允许 50 个用户,个人家庭使用完全够用。就算家里人有五六个,加上自己的各种邮箱别名,也很难超过 50。不过还是要注意,Access 的验证页面会暴露你的团队名,虽然单看团队名没什么风险,但最好不要把它当密码一样到处分享。免费版也支持邮箱验证码,配合强密码的使用习惯,安全度比裸奔高了一个量级。

5. 踩坑记录:从 502 到自启动,我把能踩的坑都踩了一遍

按理说“傻瓜操作”应该一次就成,但我实际配置的时候还是踩了几个坑。写出来帮你省时间,也当给自己备忘。如果你照着上面的步骤做,大概率会比你预期顺利,但万一遇到问题,这一章就是排错手册。

5.1 最常见:HTTP 502 Bad Gateway

外部访问域名返回 502,是 Tunnel 方案里出现频率最高的问题。完整的排查链路如下:

  1. 先看 Tunnels 页面里的隧道状态。如果状态不是 Healthy,说明连接器没起来,回到第 3 章检查 cloudflared 安装和运行命令。
  2. 如果状态 Healthy 但仍然 502,检查 Public Hostname 配置里的 Service Type 和 URL。最常见的情况是本地服务本身是 HTTPS 自签证书,但你在面板里写了 HTTP,或者反过来。
  3. 在 cloudflared 所在机器上,用 curl 直接访问本地端口,确认源站真能通。例如:
curl http://127.0.0.1:8096
  1. 如果服务不在 cloudflared 同一台机器上,确保从 cloudflared 所在机器能用内网 IP 访问对方服务:
curl http://192.168.1.20:8096
  1. 如果本地服务对 Host 请求头有要求,或者需要特定路径才能正确响应,需要在 Public Hostname 的高级配置里设置 Host Header 或路径规则。

502 的本质就是 cloudflared 已经拿到了请求,但它访问源站时失败了。所以排查重点永远在“源站能否被 cloudflared 正常访问”,而不是怀疑外部网络。

5.2 本地服务证书不受信任导致的连接失败

如果你本地服务用的是 HTTPS,而且证书是自签的,cloudflared 去访问源站时会因为证书不受信任而拒绝连接,表现就是 502 或类似 TLS 错误。最省事的办法是把 Public Hostname 里的 Service Type 改成 HTTP,让 cloudflared 和源站之间走明文 HTTP 就行,因为外部用户访问你的域名仍然走 HTTPS,最终链路的安全由 Cloudflare 边缘到浏览器的 HTTPS 保证。

如果因为某些原因,本地服务必须用 HTTPS 访问,可以在 Public Hostname 配置的高级 TLS 设置里关闭 TLS 校验。但我要多说一句:如果源站是自签证书,你关闭校验等于把从 cloudflared 到源站这段当作可信环境,一般只建议在家庭内网或个人设备上这么做。

5.3 开机自启动,以及如何切换运行方式

用cloudflared service install <token>安装的系统服务,默认已经开机自启,不用再额外配置。但如果你之前是前台运行测试的,后来想转成服务,需要在面板 Tunnel 页面重新复制安装命令,然后先卸载再安装:

sudo cloudflared service uninstall sudo cloudflared service install <token>

Windows 上操作后可以执行sc query cloudflared查看服务状态。如果是 NAS 上的 Docker 部署,建议在 docker run 参数加上--restart=unless-stopped,并把配置目录挂载好,这样重启容器或重启 NAS 后隧道能自动恢复。这一条看着简单,但很多朋友配置完当天没问题,机器重启之后才发现服务没起来。

5.4 本地服务 host 绑定问题

很多服务默认只监听127.0.0.1,这在 cloudflared 和源站服务在同一台机器时完全没问题。但如果你把 cloudflared 跑在 NAS 的 Docker 容器里,而源站服务是宿主机上的进程,容器内访问localhost指的不是宿主机,而是容器自己,就会出现“明明服务在跑,隧道就是不通”的诡异问题。

解决办法有两个:一是把服务监听地址改成0.0.0.0或这个机器所在的内网 IP;二是在 Docker 容器里通过host.docker.internal来访问宿主机服务。改监听地址前考虑一下安全,如果这个服务本来只在本机用,改监听后记得靠防火墙限制访问来源,只允许 cloudflared 所在容器或机器访问该端口。

5.5 关于速度、延迟和使用建议

最后聊一点真实体验。Cloudflare Tunnel 免费版在流量上没有明显的严格限制,但延迟和速度取决于 Cloudflare 边缘节点到你家的链路质量。我自己用下来,控制类应用、网页管理界面、文件小传都没问题,但如果要从家里 NAS 拉几个 GB 的视频文件,速度就不一定比 frp 走国内服务器快。

资源占用方面,cloudflared 进程在 NAS 上跑着,内存占用几十 MB,平时 CPU 几乎为零,完全不用担心影响其他服务。如果你有长期传输大文件的需求,建议保留 frp 作为备选,把 Cloudflare Tunnel 用在访问控制和日常使用上。如果你之前用端口映射暴露过服务,记得在 DNS 里清理旧的 A 记录,避免真实 IP 继续暴露。内网穿透工具只是第一步,真正让服务跑得长久又安心的,还是访问控制和持续观察日志的习惯。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/27 23:26:15

# AI 功能总览 —— 让组态会说话

AI 功能总览 —— 让组态会说话鲲鹏恒控把 AI 做进了组态软件的骨头里,不是贴一个聊天框了事。它有三条已经落地的 AI 能力,外加一张正在路上的产品蓝图。核心理念只有一句: 你说人话,AI 动手改工程;每一步看得见、拦得住、可回退。一、三条能力,一条边界能力一句话谁在用 AI①…

作者头像 李华
网站建设 2026/9/27 23:22:58

BK7258智能门铃开发实战:从视频配置到App联调全流程

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/27 23:20:20

STM32开发参考方案检索与工程适配实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/27 23:18:06

CANoe实战:LIN Slave一致性测试全流程与踩坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/27 23:17:50

KAIST CS492C/D 扩散模型笔记(三)

第一&#xff0c;高质量的3D数据非常稀缺。 第二&#xff0c;我们不应该使用任何强归纳偏置&#xff0c;例如在我们的案例中就是渲染。 https://github.com/OpenDocCN/dsai-notes-pt3-zh/raw/master/docs/kaist-cs492cd-diffmdl/img/c9002ee7ab54093eeedee435bbbd0108_5.png …

作者头像 李华