群晖 Synology + Cloudflare Tunnel 内网穿透完整教程
一、前置准备
- 一个域名,已托管到 Cloudflare(NS 已切换)
- 群晖 NAS 已安装 Container Manager(DSM 7.2+,旧版本叫 Docker)
- 需要穿透的服务在群晖上正常运行
- 群晖已开启 SSH(控制面板 → 终端机和 SNMP → 启用 SSH 服务)
二、Cloudflare 端配置
1. 开通 Zero Trust
- 登录 Cloudflare 后台,左侧点 Zero Trust
- 设置团队名称(随意),到付款页面选 Free 计划,完成开通
Free 计划支持 50 用户以内免费使用 Access,个人用完全够。
2. 创建隧道
- Zero Trust 后台 → 左侧 Networks → Tunnels
- 点 Create a tunnel → 选 Cloudflared → 下一步
- 给隧道命名(比如
synology-tunnel)→ 保存 - 安装方式选 Docker,复制页面给出的 token(后面要用)
三、群晖端部署 cloudflared
关键:必须用 host 网络模式
如果用默认 bridge 网络,容器里的
127.0.0.1是容器自己,访问不到群晖宿主机上的服务,会报connection refused。
提供两种部署方式,任选其一。
方式 A:SSH + docker-compose(推荐,最稳定)
1. SSH 登录群晖
ssh 你的群晖用户名@群晖IP2. 创建 docker-compose.yml
找一个你喜欢的目录,比如 /volume1/docker/cloudflared/:
mkdir -p /volume1/docker/cloudflaredcd /volume1/docker/cloudflared创建 docker-compose.yml:
version: '3'services: cloudflared: image: cloudflare/cloudflared:latest container_name: cloudflared network_mode: host restart: unless-stopped command: tunnel --no-autoupdate run --token 这里替换成你的token3. 启动容器
docker compose up -d如果提示
docker compose命令不存在,用docker-compose up -d。
4. 验证
docker ps | grep cloudflared确认网络模式是 host:
docker inspect cloudflared | grep NetworkMode输出必须是 "NetworkMode": "host"。
方式 B:Container Manager 图形界面
适合不想用命令行的用户。
1. 打开 Container Manager
群晖桌面 → 打开 Container Manager → 左侧 注册表 → 搜索 cloudflared → 选 cloudflare/cloudflared → 下载 → 标签选 latest。
2. 创建容器
左侧 容器 → 点 新增 → 选择 cloudflare/cloudflared:latest 镜像 → 下一步。
3. 常规设置
- 容器名称:
cloudflared - 勾选 启用自动重新启动
- 执行命令(命令栏)填入:
tunnel --no-autoupdate run --token 你的token
4. 网络设置(关键)
- 勾选 使用与 Docker Host 相同的网络(即 host 网络模式)
- 不要用默认的 bridge 网络
5. 完成创建
一路下一步,点 完成 启动容器。
6. 验证
容器列表里看到 cloudflared 运行中,详情里网络模式显示 host。
回到 Cloudflare 隧道页面,等连接器状态变绿,点 Next。
四、配置公共主机名
在隧道详情页 → Public Hostnames → Add a public hostname:
| 字段 | 填写说明 |
|---|---|
| Subdomain | 子域名前缀,比如 nas |
| Domain | 选择你的域名 |
| Path | 留空 |
| Type | HTTP |
| URL | 127.0.0.1:你的服务端口 |
关键:URL 用 127.0.0.1,不要用群晖局域网 IP
群晖虚拟机内(ESXI 环境),程序访问本机网卡 IP(如
10.0.0.3:5000)可能触发虚拟交换机回流拦截。用127.0.0.1走本地回环,不走网卡,最稳。
点 Save hostname 保存,配置立即生效,不用重启容器。
五、验证
浏览器访问 https://子域名.你的域名,能正常打开页面即成功。
本地验证服务是否正常(群晖 SSH 执行):
curl http://127.0.0.1:你的服务端口能返回内容说明服务正常。
六、多服务配置
在 Public Hostnames 里逐个添加,每个服务对应一个子域名:
| 子域名 | URL | 说明 |
|---|---|---|
dsm | 127.0.0.1:5000 | 群晖 DSM 管理界面 |
photo | 127.0.0.1:80 | Synology Photos(如Web Station) |
music | 127.0.0.1:8080 | 音乐服务 |
download | 127.0.0.1:9000 | 下载服务 |
每个都用 127.0.0.1:端口,host 网络模式下都能正常访问。
七、常见问题排查
问题 1:502 Bad Gateway,日志报 dial tcp 127.0.0.1:端口: connect: connection refused
原因:cloudflared 容器不是 host 网络模式。
解决:
- docker-compose 方式:确认
docker-compose.yml里有network_mode: host,重建容器Terminal window docker compose down && docker compose up -d - 图形界面方式:编辑容器 → 网络 → 勾选”使用与 Docker Host 相同的网络”
问题 2:502,日志报 dial tcp 10.0.0.x:端口: i/o timeout
原因:URL 填了群晖局域网 IP,ESXI 虚拟交换机拦截回流流量。
解决:隧道后台把 URL 改成 127.0.0.1:端口。
问题 3:502,日志报 Host validation failed
原因:后端服务强制校验 Host 头。
解决:隧道后台编辑该域名 → Additional application settings → HTTP Host Header 填入后端服务认可的域名。
问题 4:群晖 DSM 管理界面穿透后登录跳转回内网 IP
原因:DSM 会强制跳转,需要配置 Host Header。
解决:隧道后台编辑 DSM 对应的域名 → Additional application settings → HTTP Host Header 填入你的外网域名(比如 dsm.你的域名)。
问题 5:查看 cloudflared 日志
docker logs cloudflared --tail 50图形界面用户:Container Manager → 容器 → 点 cloudflared → 日志。
日志里会明确写清楚连哪个地址失败,根据报错对应上面的问题处理。
八、安全加固:Cloudflare Access 身份验证
给隧道服务加登录验证,只有你授权的人能访问,防止公网裸奔。
配置步骤
- 进入 Zero Trust 后台 → 左侧 访问控制 → 应用程序
- 点 Add an application → 选 Self-hosted
- 填写:
- Application name:随意,比如
群晖DSM - Session duration:选
24 hours或更久 - Application domain:选你的域名,子域名填你要保护的那个(比如
dsm)
- Application name:随意,比如
- 点 Next
- Policy name:随意,比如
允许我自己 - Action:选
Allow - Include 规则里:
- 选
Email - 填你的邮箱地址(只有这个邮箱能登录访问)
- 选
- 点 Next → 点 Add application 保存
效果
以后访问受保护的子域名,会先跳转到 Cloudflare 登录页,输入你授权的邮箱,收验证码登录后才能进入服务。
多个服务
每个子域名单独建一个 Application,分别保护。或者建一个 Application,domain 那里选 *.你的域名,一次性保护所有子域名。
九、群晖特有注意事项
| 事项 | 说明 |
|---|---|
| DSM 端口 | 默认 HTTP 5000,HTTPS 5001,隧道用 HTTP 填 5000 即可 |
| DSM 登录跳转 | 必须配置 HTTP Host Header 为外网域名,否则登录后跳内网 |
| 群晖防火墙 | 控制面板 → 安全性 → 防火墙,确保不拦截 cloudflared 出站(一般默认放行) |
| Container Manager vs Docker | DSM 7.2+ 叫 Container Manager,旧版本叫 Docker,操作基本一致 |
| 群晖反向代理 | 如果用了群晖自带的反向代理(控制面板 → 登录门户 → 高级 → 反向代理),隧道地址填反代端口即可 |
| 套件 Web 服务 | 群晖套件(如 Photo Station、Audio Station)的端口在套件设置里查看 |
十、其他安全建议
| 措施 | 说明 |
|---|---|
| 改 DSM 默认端口 | 控制面板 → 登录门户 → 更改默认 5000/5001 端口 |
| 启用自动封锁 | 控制面板 → 安全性 → 自动封锁,防止暴力破解 |
| 强密码 | 群晖账号、各服务账号用强密码 |
| 不开不必要的服务 | 只穿透真正需要外网访问的 |
| 定期更新 | cloudflared 镜像、DSM 系统、各套件保持更新 |
| 配合 Access | 敏感服务(尤其是 DSM)一定要加 Access 身份验证 |
| 两步验证 | 群晖账号开启两步验证 |
十一、配置速查表
| 配置项 | 正确值 | 错误值 |
|---|---|---|
| 容器网络模式 | network_mode: host / 使用与 Docker Host 相同网络 | 默认 bridge |
| 后端服务地址 | http://127.0.0.1:端口 | http://10.0.0.x:端口 |
| DSM 管理界面 | HTTP Host Header 填外网域名 | 留空(会跳转内网) |
| 普通服务 | Host Header 留空 | 乱填 |
| Zero Trust 套餐 | Free 计划 | 未选套餐 |
附:核心原理
Cloudflare Tunnel 不需要公网 IP,原理是:
- 群晖上的 cloudflared 客户端主动向外连接 Cloudflare 全球节点
- 建立一条加密的反向隧道
- 外网用户访问你的域名 → Cloudflare → 隧道 → 群晖上的服务
全程不需要:
- 公网 IPv4
- 路由器端口映射
- DMZ 主机
- DDNS
只要群晖能正常上网就行。
支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!














