网络协议

Cloudflare Tunnel + Access:安全访问家庭 NAS

用 Cloudflare Tunnel 把家里 NAS 的管理页面和相册安全地发布到 nas.你的域名,家里不需要公网 IP、不用在路由器上开任何端口,再用 Cloudflare Access 加一道邮箱验证码登录,只有你和家人的邮箱能打开。

BINBHO · 图文教程

用 Cloudflare Tunnel 把家里 NAS 的管理页面和相册安全地发布到 nas.你的域名,家里不需要公网 IP、不用在路由器上开任何端口,再用 Cloudflare Access 加一道邮箱验证码登录,只有你和家人的邮箱能打开。

先看清成品

成品是一个运行在家里的 cloudflared 容器,它主动连到 Cloudflare,外面的人访问 https://nas.example.com 时先看到 Cloudflare 的登录页,输入白名单邮箱收到的验证码后才会进入 NAS。本文在 Linux 上实际运行了 cloudflared 2026.10.2 的规则校验:配置文件校验通过,三条访问地址分别匹配到 NAS、相册和兜底 404 规则,并演示了缺少兜底规则时的报错。创建隧道和 Access 应用需要登录 Cloudflare 后台,这部分没有在本文环境中操作。

注意:只发布你自己的设备和服务。公司内网服务在发布前要得到公司 IT 的书面许可,私自打通内网可能违反公司规定。Tunnel 用来发布网站和服务,不要拿它搭建翻墙代理或其他违反当地法律法规的用途。

做完之后你会得到什么?

成果 说明
隧道 家里主动连出,路由器不开端口
公网地址 nas.example.com、photos.example.com,自动 HTTPS
登录保护 Access 邮箱验证码,只放行白名单
容器化 cloudflared 用 Docker 运行,开机自启

需要准备哪些硬件和环境?

项目 要求 说明
常开设备 NAS 本身(支持 Docker 的型号)、迷你主机或树莓派 运行 cloudflared
网络 能访问外网,出站 7844 端口不被拦截 官方建议先做连通性检查
域名 已添加到 Cloudflare 并使用其 DNS example.com 换成你的域名
Cloudflare One 首次进入时创建团队名,可选免费计划 Access 登录页需要
NAS 服务 例如管理页 https://192.168.1.10:5001,相册 http://192.168.1.10:2342 换成你实际的地址和端口

第一步:怎样创建隧道?

1. 在后台创建

登录 Cloudflare 后台,进入 Networking → Tunnels,点 Create a tunnel,起名 home-nas。

2. 复制令牌

选择 Docker 作为运行环境,页面会给出一条带 --token 的命令。只复制令牌部分,保存到项目的 .env:

TUNNEL_TOKEN=粘贴后台给出的隧道令牌

注意:令牌等同于隧道的钥匙,拿到它的人可以冒充你的隧道。不要截图外传,不要提交到 Git。

3. 用 Compose 运行

services:
  cloudflared:
    image: cloudflare/cloudflared:2026.10.2
    command: tunnel --no-autoupdate run
    environment:
      # 在 Cloudflare 后台创建隧道时给出的令牌,写在 .env 里
      TUNNEL_TOKEN: ${TUNNEL_TOKEN}
    restart: unless-stopped
    # 和 NAS 网页服务在同一台机器时,用 host 网络最简单:路由里填 http://localhost:端口
    network_mode: host
docker compose up -d
docker compose logs -f cloudflared

日志里出现 Registered tunnel connection 字样,后台隧道状态变为 Healthy,说明连接成功。

第二步:怎样把 NAS 页面发布出去?

1. 添加路由

在隧道详情页的 Routes 标签点 Add route → Published application:

字段 NAS 管理页 相册
Subdomain nas photos
Domain example.com example.com
Service URL https://192.168.1.10:5001 http://192.168.1.10:2342

NAS 管理页通常是自签名证书,需要在该路由的 TLS 设置里开启 No TLS Verify,否则 cloudflared 会拒绝连接。

2. 先别急着打开

官方文档说明:添加路由后,互联网上任何人都能访问这个地址。所以下一步必须先加 Access,再把地址告诉家人。

第三步:怎样加上登录保护?

1. 开启邮箱验证码登录

进入 Cloudflare One(Zero Trust)后台,在身份提供方设置(新版后台位于 Integrations → Identity providers)里添加或确认 One-time PIN 登录方式已启用。

2. 创建 Access 应用

在 Access controls → Applications 添加 Self-hosted 应用:

设置 填写
应用名称 家庭 NAS
应用域名 nas.example.com,再添加 photos.example.com
会话时长 按需要,例如 24 小时
策略名称 家人
动作 Allow
规则 Emails:你和家人的邮箱

3. 检查结果

操作 期望
手机关掉 Wi-Fi,用流量打开 https://nas.example.com 出现 Cloudflare Access 登录页
输入白名单邮箱 收到验证码,登录后进入 NAS
输入其他邮箱 收不到验证码或被拒绝
访问 https://abc.example.com 不会进入任何家里的服务

后台的隧道和 Access 菜单名称会随版本调整,找不到时用后台顶部的搜索。

第四步:本地管理的配置文件怎么写?

如果你更喜欢把路由规则写在文件里(方便备份和版本管理),可以用本地管理的隧道:

cloudflared tunnel login
cloudflared tunnel create home-nas
cloudflared tunnel route dns home-nas nas.example.com

create 会输出隧道 ID 并生成凭据 JSON 文件。然后编写 config.yml:

# 方式二:本地管理的隧道(cloudflared tunnel create 生成凭据后使用)
tunnel: 6ff42ae2-765d-4adf-8112-31c55c1551ef
credentials-file: /etc/cloudflared/6ff42ae2-765d-4adf-8112-31c55c1551ef.json

ingress:
  # NAS 管理页面
  - hostname: nas.example.com
    service: https://192.168.1.10:5001
    originRequest:
      noTLSVerify: true        # NAS 用的是自签名证书
  # 家庭相册
  - hostname: photos.example.com
    service: http://192.168.1.10:2342
  # 兜底规则:其他请求一律 404,必须放在最后
  - service: http_status:404

1. 校验规则

cloudflared tunnel --config config.yml ingress validate
cloudflared tunnel --config config.yml ingress rule https://nas.example.com/

本文实际输出:

Validating rules from config.yml
OK
Matched rule #0 	hostname: nas.example.com 	service: https://192.168.1.10:5001

https://photos.example.com/album 匹配到规则 #1,https://other.example.com/ 匹配到兜底的 404 规则 #2。

2. 运行

cloudflared tunnel --config config.yml run home-nas

本地管理和后台管理二选一即可,不要对同一条隧道混用。

出问题时该怎么调?

1. 校验报错 The last ingress rule must match all URLs

本文故意删掉兜底规则后得到:

Validation failed: The last ingress rule must match all URLs (i.e. it should not have a hostname or path filter)

在 ingress 最后加一条不带 hostname 的规则,例如 - service: http_status:404。

2. 打开网页显示 502 Bad Gateway

原因 检查
服务地址写错 在运行 cloudflared 的机器上 curl -k https://192.168.1.10:5001
容器网络隔离 用 network_mode: host,或确保容器能访问 NAS 的局域网地址
自签名证书 开启 No TLS Verify
HTTP 和 HTTPS 写反 按 NAS 实际协议填写

3. 隧道一直是 Inactive 或 Down

查看 docker compose logs cloudflared。常见原因是令牌复制不完整,或者网络拦截了出站的 7844 端口。按官方“连通性预检查”文档排查。

4. 家人收不到验证码

检查邮箱是否在策略的 Emails 列表里、是否被归入垃圾邮件。不在白名单的邮箱不会收到验证码,这是正常的安全行为。

常见问题怎么处理?

现象 原因 解决方法
证书错误 用了多级子域名如 a.b.example.com 用一级子域名,或按文档申请高级证书
登录后又跳回登录页 浏览器拦截第三方 Cookie 允许该域名的 Cookie
NAS 的手机 App 连不上 App 不支持 Access 登录页 App 只在家里用局域网地址,或查官方的服务令牌方案
上传大文件失败 经过 Cloudflare 有请求体大小限制 大文件在局域网内传
想临时关闭外网访问 不需要时 docker compose stop cloudflared
视频卡顿 经过隧道多绕一段路 局域网内直接访问 NAS 地址

项目资源

用途 地址
Tunnel 概述 https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/
后台创建隧道 https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/get-started/create-remote-tunnel/
Access 自托管应用 https://developers.cloudflare.com/cloudflare-one/access-controls/applications/http-apps/self-hosted-public-app/
一次性验证码登录 https://developers.cloudflare.com/cloudflare-one/integrations/identity-providers/one-time-pin/
cloudflared 下载 https://github.com/cloudflare/cloudflared/releases
cloudflared 镜像 https://hub.docker.com/r/cloudflare/cloudflared
Zero Trust 套餐 https://www.cloudflare.com/plans/zero-trust-services/

建议先发布一个不重要的服务(比如 Homepage 首页),走完“隧道 → 路由 → Access”三步,用手机流量确认必须登录才能打开。

确认保护生效后,再把 NAS 管理页和相册加进同一个 Access 应用。