折腾 NAS 外网访问这件事,前前后后踩了不少坑。
一开始想过最常见的几种方案:
- 端口映射:简单直接,但风险也最高
- DDNS:能用,但总感觉暴露面太大
- FRP:灵活是灵活,就是还得额外维护一台服务器
最后折腾下来,我自己最喜欢的还是这一套:
Cloudflare Tunnel + Cloudflare Access 权限控制
这套方案最吸引我的地方很明确:
- 不需要公网 IP
- 不需要开放端口
- 全程 HTTPS
- 还能额外加一层访问权限控制
一、整体思路
这套方案的访问链路其实很简单:
浏览器 → Cloudflare → Tunnel → NAS
它和传统端口映射最大的不同在于:
不是外网主动连接你的 NAS,而是 NAS 主动连接 Cloudflare。
这样带来的好处也很直接:
- 外网看不到你的真实 IP
- 公网扫不到你的 NAS 端口
- 访问链路更干净,安全性也更高
二、准备环境
这篇文章里的环境信息我都做了脱敏,公开发博客也更安全一些。
准备条件大致如下:
- 群晖 NAS(DSM)
- 一个已经接入 Cloudflare 的域名,例如
example.com - NAS 已安装 Docker,也就是群晖里的 Container Manager
三、创建访问域名
先在 Cloudflare 的 DNS 里准备一个子域名,例如:
nas.example.com
这里不需要手动填写 IP,因为后面 Tunnel 会自动接管。
四、创建 Cloudflare Tunnel
进入 Cloudflare Zero Trust 后台,路径如下:
Zero Trust → Networks → Tunnels
新建一个 Tunnel 之后,Cloudflare 会给你一段 Token。
类似这样:
eyJhIjoiXXXXXX...
后面在群晖 Docker 部署 cloudflared 的时候,就要用到它。
五、在群晖上部署 cloudflared
我这里是直接用 Docker 跑,最省事。
1. 拉起容器
docker run -d \
--name=cloudflared \
--restart=unless-stopped \
cloudflare/cloudflared:latest \
tunnel --no-autoupdate run --token YOUR_TOKEN
把上面的 YOUR_TOKEN 替换成你自己的 Token 即可。
2. 查看容器状态
docker ps
3. 查看运行日志
docker logs -f cloudflared
如果日志里能看到类似下面的内容,说明 Tunnel 已经连上 Cloudflare:
Connected to Cloudflare
六、配置 Tunnel 访问规则
接下来回到 Cloudflare Tunnel 后台,给它加一条 Public Hostname 规则。
例如:
Hostname: nas.example.com
Service: https://192.168.x.x:5001
这里顺便把群晖 DSM 的常见端口也整理一下:
| 服务 | 端口 |
|---|---|
| DSM HTTP | 5000 |
| DSM HTTPS | 5001 |
七、一个非常容易踩的坑
这个坑我自己也踩过一次,就是协议和端口写反了。
错误写法:
Service: https://192.168.x.x:5001
报错信息通常会是:
400 Bad Request
The plain HTTP request was sent to HTTPS port
这个报错的核心意思其实很简单:
你配置进去的协议,和 NAS 实际监听的协议不匹配。
所以这里一定要按实际情况填写。
正确写法
如果你的群晖后台走的是 HTTP:
Service: http://192.168.x.x:5000
如果你的群晖后台走的是 HTTPS:
Service: https://192.168.x.x:5001
八、Cloudflare 权限控制(这一步很关键)
很多人搭完 Tunnel 就结束了,但我觉得真正让这套方案完整起来的,其实是 Cloudflare Access。
因为 Tunnel 解决的是“怎么安全连进来”,而 Access 解决的是“谁可以进来”。
进入路径如下:
Zero Trust → Access → Applications
然后新建一个应用:
Add an application → Self-hosted
1. 应用信息
Application name: NAS
Domain: nas.example.com
2. 访问策略
这里我比较推荐最简单也最实用的方式:直接限制自己的邮箱。
例如:
Action: Allow
Include → Emails → [email protected]
这样配置之后,只有你自己的邮箱通过验证,才能访问这个地址。
如果是多人一起用,也可以这样写:
Include → Emails → [email protected], [email protected]
如果你是给公司或团队内部用,也可以按邮箱域名来限制:
Include → Email domain → example.com
九、开启 Access 后是什么效果
配置完成之后,再访问:
https://nas.example.com
不会立刻进入 NAS,而是会先跳到 Cloudflare Access 的验证页面。
大致流程是这样:
- 访问
nas.example.com - 跳转到 Cloudflare 登录验证
- 输入允许访问的邮箱
- 完成验证后,才会进入群晖 DSM
也就是说,即使别人知道了你的访问地址,也不代表他能打开。
十、再补几项我觉得值得开的安全设置
1. One-Time PIN
适合个人用,邮箱收验证码登录,简单直接。
2. 2FA 双因素认证
如果你对安全更敏感,建议一起开。
3. Session Duration
这个可以控制登录有效期。
例如设置成:
24h
这样验证一次之后,24 小时内不用反复登录。
十一、Cloudflare SSL 设置
这一项也最好顺手检查一下。
路径:
SSL/TLS → Overview
我自己更推荐:
Full (strict)
这样整体更稳,也更符合这套方案的定位。
十二、访问体验和国内使用感受
这一点也实话实说。
Cloudflare Tunnel 的确很方便,但在国内访问体验有时候会受线路影响,不一定总是完美。
所以我的思路一直是分开看:
内网访问时,直接走本地地址。
https://192.168.x.x:5001
外网访问时,再走 Cloudflare Tunnel。
https://nas.example.com
这样实际体验通常会更合理一些。
十三、这套方案还能顺手扩展什么
既然 Tunnel 已经搭好了,其实不只可以给 DSM 用。
很多群晖上的服务也都可以顺手统一起来,例如:
nas.example.com → DSM
drive.example.com → 文件管理
photo.example.com → 相册服务
note.example.com → 笔记系统
这样做的好处是,后面整个自建服务体系会很整齐。
十四、最后总结
这套方案我自己用下来的感受很明确:
- 不暴露公网端口
- 不依赖公网 IP
- 全程 HTTPS
- 还能叠加 Cloudflare Access 做权限控制
如果只是想让 NAS 能被远程访问,其实方法很多。
但如果你还希望:
- 尽量安全
- 尽量干净
- 尽量少折腾公网暴露问题
那 Cloudflare Tunnel 确实是一个很值得长期使用的方案。
一句话总结:
Cloudflare Tunnel 负责把门藏起来,Cloudflare Access 负责决定谁能进门。