Logo
Overview

Cloudflare Tunnel 配置笔记:新 VPS 上安全暴露服务的最小成本方案

2025/12/22
约 7 分钟阅读

为什么用 Cloudflare Tunnel?

Cloudflare Tunnel 的核心价值很简单:让你的服务器不必开放入站端口(甚至不必暴露真实源站 IP),也能把服务安全地暴露到公网域名

它的工作方式是:

  • 你在 VPS 上运行 cloudflared
  • cloudflared 主动向 Cloudflare 发起出站连接
  • 用户访问你的域名 → Cloudflare 边缘接入 → 通过 Tunnel 把请求转发回你的 VPS 本机服务

✅ 优点(运维角度):

  • 新 VPS 上不必先搞复杂防火墙/反代
  • 源站服务可以只监听 127.0.0.1,天然减少被扫描/直连风险
  • 可叠加 Cloudflare Access 做二次认证、审计、策略控制

⚠️ 适用边界:

  • Tunnel 更适合 HTTP/HTTPS(Web 服务) 这类“域名入口”的服务暴露
  • 非 HTTP 的 TCP 服务也能做,但通常要用到额外能力或不同方案(本文不展开)

最推荐的安全落地模型(先定目标)

新 VPS 上我推荐的“最少折腾 + 安全不拉胯”的模型是:

  1. 服务只监听本机127.0.0.1:PORT
  2. Cloudflare Tunnel 回源也指向本机http://127.0.0.1:PORT
  3. 用独立子域名暴露:app.example.com
  4. (强烈建议)叠加 Cloudflare Access:只允许自己/团队访问

这样做的好处是:
即使别人知道你的真实 IP,也无法绕过 Cloudflare 直连你的服务(因为服务根本没在公网网卡上监听)。


前置条件

  • 你已把域名 DNS 托管到 Cloudflare(NS 已接入)
  • 一台新 VPS(示例以 Ubuntu 24 为主)
  • 服务器能出网访问 Cloudflare(出站 443 需可用)

安装 cloudflared(推荐二进制方式,省心)

我更推荐二进制安装:不依赖 apt 源/GPG key,成功率更高。

1)下载并安装

Terminal window
sudo rm -f /usr/local/bin/cloudflared
Terminal window
sudo curl -fL https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 -o /usr/local/bin/cloudflared
Terminal window
sudo chmod +x /usr/local/bin/cloudflared
Terminal window
/usr/local/bin/cloudflared --version

看到版本号就 OK ✅


创建 Tunnel:两条路线

你可以用 控制台(最省事)命令行(更可控)

路线 A:Cloudflare Zero Trust 控制台(推荐新手)

1)创建 Tunnel

在 Cloudflare 控制台:

  • 进入 Zero Trust
  • 进入 Networks → Tunnels
  • Create tunnel → Cloudflared
  • 创建完成后会给你一条带 token 的安装命令

2)在 VPS 执行安装命令(注意:一条一行)

控制台通常会给类似命令(示例):

Terminal window
sudo /usr/local/bin/cloudflared service install <TOKEN>

执行后验证:

Terminal window
sudo systemctl status cloudflared --no-pager

看到 active (running) 就说明 tunnel 已连上 Cloudflare ✅

3)绑定域名入口(Public Hostname)

在 Tunnel 详情页添加 Public Hostname

  • Hostname:app.example.com
  • Service:http://127.0.0.1:PORT

保存后,访问:

  • https://app.example.com

就会转发到你的本机服务。


路线 B:命令行创建(适合喜欢可控/可迁移)

1)登录授权(会打开浏览器授权)

Terminal window
/usr/local/bin/cloudflared tunnel login

2)创建 tunnel

Terminal window
/usr/local/bin/cloudflared tunnel create my-tunnel

3)写配置文件(YAML)

创建目录:

Terminal window
sudo mkdir -p /etc/cloudflared

新建 /etc/cloudflared/config.yml

tunnel: <TUNNEL-UUID>
credentials-file: /etc/cloudflared/<TUNNEL-UUID>.json
ingress:
- hostname: app.example.com
service: http://127.0.0.1:PORT
- service: http_status:404

ingress 最后一条建议保留 http_status:404,避免未匹配域名被意外转发。

把 credentials 文件放到对应路径(创建 tunnel 后会生成 json,按你的实际位置移动):

Terminal window
sudo mv ~/.cloudflared/<TUNNEL-UUID>.json /etc/cloudflared/

4)绑定 DNS

Terminal window
/usr/local/bin/cloudflared tunnel route dns my-tunnel app.example.com

5)运行 tunnel

Terminal window
/usr/local/bin/cloudflared tunnel run my-tunnel

systemd 常驻(建议开机自启)

如果你走路线 A(service install),通常已经自动创建 systemd 服务了。

如果你走路线 B(自建 config.yml),可以用下面这种方式创建服务(示例):

创建 /etc/systemd/system/cloudflared.service

[Unit]
Description=cloudflared
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/local/bin/cloudflared --no-autoupdate tunnel run --config /etc/cloudflared/config.yml
Restart=on-failure
RestartSec=3
User=root
[Install]
WantedBy=multi-user.target

启用并启动:

Terminal window
sudo systemctl daemon-reload
Terminal window
sudo systemctl enable --now cloudflared

查看状态:

Terminal window
sudo systemctl status cloudflared --no-pager

看日志:

Terminal window
sudo journalctl -u cloudflared --no-pager -n 80

新 VPS 的“安全配置清单”(建议照做)

1)服务只监听本机(强烈建议)

如果你的服务支持设置监听地址,请尽量改成:

  • 127.0.0.1:PORT

这样就算服务器暴露了公网 IP,也无法通过 IP:PORT 直连服务。

2)Tunnel 回源永远用本机地址

  • ✅ 推荐:http://127.0.0.1:PORT
  • ❌ 不推荐:http://真实IP:PORT

原因:回源写真实 IP,等于让 cloudflared 走公网路径“绕一圈”,更容易引入防火墙/路由/监听地址不一致导致的 502,也可能削弱“不可直连”的效果。

3)给每个服务用独立子域名

例子:

  • app.example.com → 服务 A
  • api.example.com → 服务 B

不要把所有东西都塞到同一个域名的复杂 path 下,维护成本高、排障也难。

4)开启 Cloudflare Access(强烈建议)

Tunnel 解决“网络入口”,Access 解决“身份与授权”。

最常用做法:

  • 只允许自己的邮箱登录
  • 开启一次性验证码(OTP)
  • 限制国家/地区(可选)
  • 加设备姿态策略(团队场景可选)

5)保护 token:当作“密钥”处理

  • token 不要出现在聊天、截图、博客
  • 怀疑泄露:删除 connector / 重建 tunnel,重新生成 token
  • 日志/命令输出如果包含 token,记得打码再分享

常见问题排查

1)访问域名出现 502

99% 是 cloudflared 连不上回源

  • 回源写错端口
  • 服务没启动
  • 服务只监听 127.0.0.1,但回源却写了真实 IP
  • 回源是 HTTPS,自签证书导致校验失败(需要调整回源 TLS 设置)

快速定位(每条一行):

Terminal window
sudo journalctl -u cloudflared --no-pager -n 80
Terminal window
ss -lntp | grep :PORT
Terminal window
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:PORT/

2)访问域名出现 404

看你的 ingress 规则是否匹配:

  • 是否绑定了正确的 hostname
  • ingress 顺序是否正确(从上到下匹配)
  • 最后一条是否是 http_status:404(未命中就会 404,这是正常行为)

3)改了控制台配置但不生效

让 cloudflared 重启拉新配置:

Terminal window
sudo systemctl restart cloudflared

然后看日志里是否出现 “Updated to new configuration”。


结尾:我的实践建议(最少折腾版)

如果你只想要一个“通用模板”,我建议记住这 4 句话:

  • 服务只监听 127.0.0.1
  • Tunnel 回源也写 127.0.0.1
  • 每个服务一个子域名
  • 入口加 Cloudflare Access

这样配置出来的新 VPS,从安全和维护角度都很舒服