VoHive 原本只运行在家中 Ubuntu 服务器的 http://192.168.1.21:7575。我希望在外面也能查看设备和短信通知,但又不想把 7575 端口直接映射到公网。
最后采用的方案是:
浏览器
↓ HTTPS
Cloudflare Access(邮箱验证码、访问策略)
↓
Cloudflare Tunnel
↓ 主机主动建立的出站连接
Ubuntu 上的 cloudflared
↓ 127.0.0.1:7575
VoHive
最终访问地址为 https://vohive.somlar.com。未通过 Access 身份验证的请求不会到达 VoHive;通过后还需要面对 VoHive 自身的登录验证,相当于保留了两层防护。
为什么不直接做端口转发
直接在路由器上把公网端口映射到 192.168.1.21:7575 虽然简单,但会把应用登录页直接暴露给互联网,也要求家庭宽带拥有可用的公网入口。
Cloudflare Tunnel 的 cloudflared 由内网主机主动向 Cloudflare 建立出站连接,因此:
- 不需要在爱快、OpenWrt 或上级路由器上开放入站端口;
- 不依赖固定公网 IPv4;
- 浏览器只访问 Cloudflare,不会看到源站地址;
- 可以在应用前增加 Cloudflare Access 身份验证和白名单策略。
这并不代表可以忽略源站安全。VoHive 自身密码、系统更新、备份和最小权限仍然需要保留。
准备条件
- 一个已接入 Cloudflare DNS 的域名;
- 一台可以访问互联网、同时能访问 VoHive 的 Linux 主机;
- VoHive 已能在服务器本机通过
http://127.0.0.1:7575访问; - 具有 Cloudflare Zero Trust 配置权限。
本文使用 Ubuntu amd64。其他架构需要把安装包名称中的 amd64 换成对应架构。
1. 安装 cloudflared
方法一:直接安装官方 deb 包
cd /tmp
wget -O cloudflared-linux-amd64.deb \
https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared-linux-amd64.deb
cloudflared --version
如果 dpkg 报告缺少依赖,可以执行:
sudo apt-get -f install
sudo dpkg -i /tmp/cloudflared-linux-amd64.deb
方法二:使用 Cloudflare APT 软件源
sudo mkdir -p --mode=0755 /usr/share/keyrings
curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg \
| sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null
echo 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared any main' \
| sudo tee /etc/apt/sources.list.d/cloudflared.list
sudo apt-get update
sudo apt-get install cloudflared
如果 Ubuntu 自己的软件源出现 403,应先检查 /etc/apt/sources.list 和 /etc/apt/sources.list.d/ 中的镜像地址。这和 Tunnel 本身不是同一个问题,但会阻止 APT 正常安装依赖。
2. 登录 Cloudflare 并创建 Tunnel
在 Ubuntu 上执行:
cloudflared tunnel login
命令会输出一个授权网址。用浏览器打开它,选择托管目标域名的 Cloudflare Zone 并授权。成功后,本机通常会生成:
~/.cloudflared/cert.pem
创建名为 vohive 的 Tunnel:
cloudflared tunnel create vohive
记下输出中的 Tunnel UUID。命令还会生成类似下面的凭据文件:
~/.cloudflared/<TUNNEL-UUID>.json
不要把 cert.pem、Tunnel JSON 凭据、Access Token 或任何密码提交到 Git 仓库。
可以查看已有 Tunnel:
cloudflared tunnel list
3. 配置域名与源站
先让 Cloudflare 为子域名创建指向 Tunnel 的 DNS 记录:
cloudflared tunnel route dns vohive vohive.somlar.com
将凭据放入系统目录:
sudo mkdir -p /etc/cloudflared
sudo cp ~/.cloudflared/<TUNNEL-UUID>.json /etc/cloudflared/
sudo chmod 600 /etc/cloudflared/<TUNNEL-UUID>.json
创建 /etc/cloudflared/config.yml:
tunnel: <TUNNEL-UUID>
credentials-file: /etc/cloudflared/<TUNNEL-UUID>.json
ingress:
- hostname: vohive.somlar.com
service: http://127.0.0.1:7575
- service: http_status:404
最后一条 http_status:404 是兜底规则。没有匹配前面 hostname 的流量会直接返回 404,而不会被意外转发到其他本地服务。
检查配置:
sudo cloudflared tunnel ingress validate
sudo cloudflared tunnel ingress rule https://vohive.somlar.com
4. 安装 systemd 服务
先确认前台运行正常:
sudo cloudflared --config /etc/cloudflared/config.yml tunnel run
看到连接成功后按 Ctrl+C 退出,再安装系统服务:
sudo cloudflared --config /etc/cloudflared/config.yml service install
sudo systemctl enable --now cloudflared
检查状态和日志:
systemctl status cloudflared --no-pager
journalctl -u cloudflared -n 100 --no-pager
需要持续观察时:
journalctl -u cloudflared -f
此时域名已经能够经过 Tunnel 到达 VoHive,但不要止步于此。下一步要用 Access 给入口加锁。
5. 创建 Cloudflare Access 应用
进入 Cloudflare Zero Trust 控制台:
- 打开“访问控制 → 应用程序”;
- 新建“自托管”应用;
- 应用名称填写
VoHive; - 公共主机名填写
vohive.somlar.com; - 会话持续时间根据需要设置,本文使用 24 小时;
- 新建一个
Allow策略; Include选择“电子邮件”,填写允许访问的邮箱;- 保存策略并创建应用。
策略应该尽量具体,不要为了省事直接选择“所有人”。如果有多人使用,可以加入多个邮箱,或者接入 Google、GitHub、Microsoft Entra ID 等身份提供商。

创建完成后,访问域名会先显示 Cloudflare Access 登录页。本文使用邮箱一次性验证码:

6. 验证是否真的被 Access 保护
不要只看网页能否打开,还应从未登录状态检查 HTTP 响应:
curl -I https://vohive.somlar.com
正确结果通常包括:
HTTP/2 302
location: https://<TEAM-NAME>.cloudflareaccess.com/cdn-cgi/access/login/...
www-authenticate: Cloudflare-Access ...
这表明请求首先被重定向到 Cloudflare Access,而不是直接看到 VoHive 登录页。
还需要完成以下测试:
- 不在白名单中的邮箱不能通过验证;
- 白名单邮箱可以收到验证码并登录;
- Access 登录成功后能正常打开 VoHive;
- 重启 Ubuntu 后
cloudflared自动恢复; - 家中路由器没有为 7575 创建公网端口转发;
- 停止
cloudflared后公网入口无法访问源站。
重启后的检查命令:
sudo reboot
# 重新连接服务器后
systemctl is-enabled cloudflared
systemctl is-active cloudflared
journalctl -u cloudflared -b --no-pager
日常维护与故障排查
域名返回 502
通常是 Tunnel 在线,但 cloudflared 无法连接本地 VoHive:
curl -I http://127.0.0.1:7575
ss -lntp | grep 7575
journalctl -u cloudflared -n 100 --no-pager
确认 VoHive 进程存在、监听端口正确,并且 config.yml 没有写错协议或端口。
域名无法解析
dig vohive.somlar.com
cloudflared tunnel list
cloudflared tunnel info vohive
检查 DNS 记录是否指向正确的 Tunnel,以及域名是否确实由当前 Cloudflare 账户管理。
能看到 VoHive,却没有 Access 登录页
这说明 Access 应用可能没有覆盖当前 hostname,或者策略配置过宽。检查:
- Access 应用的公共主机名是否完全等于访问域名;
- 应用是否启用;
- 是否存在
Bypass或“所有人”规则; - 浏览器是否还保留着有效的 Access Cookie。可用无痕窗口再次测试。
Tunnel 服务没有自动启动
sudo systemctl daemon-reload
sudo systemctl enable --now cloudflared
sudo systemctl status cloudflared --no-pager
同时确认 /etc/cloudflared/config.yml 和凭据文件路径正确,服务用户能够读取 JSON 凭据。
安全清单
- 不开放 VoHive 的公网端口转发;
- Access 策略只允许明确的邮箱或身份组;
- 保留 VoHive 自身登录验证;
- 不在博客、截图或 Git 中公开 Tunnel 凭据和 Token;
- 定期更新 Ubuntu、VoHive 与 cloudflared;
- 定期检查 Access 审计日志和
cloudflared服务日志; - 备份 VoHive 配置,但不要把明文密钥提交到仓库;
- 如果邮箱账户支持,开启 MFA。
常用命令速查
# 版本
cloudflared --version
# Tunnel
cloudflared tunnel list
cloudflared tunnel info vohive
# 配置检查
sudo cloudflared tunnel ingress validate
sudo cloudflared tunnel ingress rule https://vohive.somlar.com
# 服务状态
systemctl is-active cloudflared
systemctl status cloudflared --no-pager
# 日志
journalctl -u cloudflared -n 100 --no-pager
journalctl -u cloudflared -f
# 公网入口检查
curl -I https://vohive.somlar.com
# 本地源站检查
curl -I http://127.0.0.1:7575
ss -lntp | grep 7575
参考资料
这套方案的关键不是“给内网服务套一个域名”,而是把公网入口、传输通道和身份认证拆开处理:Tunnel 负责安全地连接内网,Access 负责决定谁能进来,VoHive 自身再负责应用内权限。这样比裸露端口更容易维护,也更适合长期运行的家庭服务。
Comments