VPS 教程
VPS 用 Cloudflare Tunnel 隐藏源站 IP(2026):Zero Trust、免开放端口、内网穿透部署指南
Cloudflare Tunnel 可以让 VPS 上的 Web 服务不直接暴露公网端口,通过 cloudflared 主动连到 Cloudflare,再由 Cloudflare 回源访问本地服务。本文讲清楚它适合什么场景、怎么部署、如何绑定域名、如何用 Access 保护后台,以及常见 Inactive、502、源站仍可直连等问题怎么排查。

很多 VPS 网站接入 Cloudflare 后,只是把 DNS 记录点成橙云代理。这样能隐藏一部分访问路径,但如果源站 IP 已经泄露,攻击者仍然可以绕过 Cloudflare,直接打你的 VPS。
Cloudflare Tunnel 解决的是另一个问题:让源站不再需要开放公网 80/443 端口。VPS 上运行一个 cloudflared 守护进程,它主动向 Cloudflare 建立 outbound-only 加密连接;外部用户访问你的域名时,请求先进 Cloudflare,再通过这条隧道转发到 VPS 本地服务。
这篇文章按 VPS 用户的真实场景讲:什么时候该用 Tunnel,怎么创建隧道,怎么发布一个自托管服务,怎么保护后台,以及常见故障怎么排查。
Cloudflare Tunnel 最适合这些需求:
| 场景 | 是否适合 | 说明 |
|---|---|---|
| 暴露博客、工具站、小型 SaaS | 适合 | 免开放源站 80/443,隐藏源站 IP |
| 暴露 n8n、Gitea、Grafana 管理后台 | 很适合 | 可配合 Cloudflare Access 做登录保护 |
| 家宽/NAT 后面的服务 | 适合 | 不需要公网 IP,也不需要端口转发 |
| 高并发下载站、大文件业务 | 谨慎 | 要考虑 Cloudflare 策略和带宽特征 |
| 邮件服务器、游戏服、任意 TCP 服务 | 不一定 | HTTP 最简单,非 HTTP 要看协议和方案 |
一句话:如果你的服务本质是 HTTP/HTTPS,并且你希望隐藏源站 IP,Tunnel 很值得用。
但它不是银弹。Tunnel 不能替你修复应用漏洞,也不能替代备份、日志和权限控制。它解决的是“入口暴露面”和“源站绕过 Cloudflare”的问题。
传统方式是:
用户 -> Cloudflare -> VPS 公网 IP:443 -> Nginx -> 应用
Tunnel 方式是:
用户 -> Cloudflare Edge -> cloudflared 隧道 -> 127.0.0.1:3000
关键区别是:cloudflared 主动从 VPS 连出去,VPS 防火墙可以关闭 80/443 入站,只保留 SSH 或甚至只走控制台/VPN 管理。
Cloudflare 官方文档也明确说明,Tunnel 使用 outbound-only connection model:cloudflared 从源站主动连接到 Cloudflare 全球网络,流量再通过这条连接双向转发。
这对 VPS 很有价值:
- 源站 IP 不必直接暴露给用户;
- 没有公网 IP 的内网服务也能发布;
- 可以把后台入口挂到 Cloudflare Access 后面;
- 防火墙策略更简单:默认拒绝入站,只允许必要管理端口。
你需要:
- 一个已经接入 Cloudflare 的域名;
- 一台能访问外网的 VPS;
- 一个本地正在运行的服务,例如
127.0.0.1:3000; - Cloudflare Zero Trust 面板访问权限。
先确认本地服务可访问:
curl -I http://127.0.0.1:3000
如果本机都访问不了,先别配置 Tunnel。Tunnel 不是应用修复工具,它只负责转发。
进入 Cloudflare Zero Trust:
Zero Trust -> Networks -> Connectors -> Cloudflare Tunnels -> Create a tunnel
选择 Cloudflared,给隧道起名,比如:
vps-main-tunnel
Cloudflare 会给你一条安装命令。Debian/Ubuntu 上大概是这种形式:
curl -L --output cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared.deb
sudo cloudflared service install <你的-token>
安装后回到面板,如果 connector 显示 Healthy,说明 VPS 已经和 Cloudflare 建立连接。
在 Tunnel 的 Public Hostname 或 Published applications 里添加:
Subdomain: app
Domain: example.com
Type: HTTP
URL: http://localhost:3000
保存后,访问:
https://app.example.com
如果服务正常,就会通过 Cloudflare Tunnel 打到 VPS 本地的 3000 端口。
这时你的应用可以只监听本地:
HOST=127.0.0.1 PORT=3000 npm start
Nginx 也可以不是公网入口,而只是本机反代层:
server {
listen 127.0.0.1:8080;
server_name _;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
然后 Tunnel 指向:
http://localhost:8080
Dashboard 安装方式通常会自动注册 systemd 服务。检查状态:
systemctl status cloudflared
journalctl -u cloudflared -n 100 --no-pager
常用命令:
systemctl restart cloudflared
systemctl enable cloudflared
如果你以后重装系统,记得重新安装 connector。Tunnel 对象在 Cloudflare 面板里,VPS 上的 cloudflared 只是连接器。
使用 Tunnel 后,公网入站端口可以大幅收紧。
如果你的站点完全通过 Tunnel 发布,可以这样:
ufw default deny incoming
ufw default allow outgoing
ufw allow OpenSSH
ufw enable
如果 SSH 也想进一步保护,可以只允许自己的 IP:
ufw allow from 你的固定IP to any port 22 proto tcp
但不要在没准备控制台/VNC/救援模式前乱关 SSH。之前已经有相关自救文章:
Tunnel 的强项不只是隐藏源站,还能和 Cloudflare Access 配合。
比如你有这些后台:
n8n.example.comgitea.example.comgrafana.example.comadmin.example.com
可以在 Zero Trust 里创建 Access Application,要求访问前必须通过:
- 邮箱 OTP;
- Google / GitHub 登录;
- 指定团队邮箱;
- 指定国家/地区或 IP 策略;
- 多因素认证。
这样即使后台应用本身登录页暴露,外面还多了一层 Cloudflare 身份验证。
推荐策略:
| 服务 | Access 建议 |
|---|---|
| 博客前台 | 不需要 Access |
| n8n / Grafana / Gitea 后台 | 强烈建议加 Access |
| Webhook URL | 不要盲目加 Access,可能影响第三方回调 |
| 内部工具 | 只允许指定邮箱或组织账号 |
先看服务:
systemctl status cloudflared
journalctl -u cloudflared -n 100 --no-pager
再确认 VPS 能访问 Cloudflare:
curl -I https://www.cloudflare.com
如果服务器在严格防火墙后面,需要确认 outbound 连接没有被拦。Cloudflare 文档提醒,受限网络里要先做 connectivity pre-check,尤其要确认到 Cloudflare 的连接可达。
常见原因:
- token 复制错;
- systemd 服务没启动;
- VPS 出站被防火墙拦;
- DNS 或系统时间异常;
- cloudflared 版本过旧。
Tunnel 已经 Healthy,但访问域名报错,通常是本地服务地址写错。
在 VPS 上测试:
curl -I http://localhost:3000
curl -I http://127.0.0.1:3000
注意 localhost 可能解析到 IPv6 ::1,而你的应用只监听 IPv4。遇到这种情况,Public Hostname 里可以明确写:
http://127.0.0.1:3000
如果你的应用要求 Host 头,可能还要在 Tunnel 的 origin request 设置里调整 HTTP Host Header。
Tunnel 配好了,不代表源站一定隐藏。你还要确认:
- DNS 里没有灰云 A 记录暴露真实 IP;
- VPS 防火墙没有继续开放 80/443;
- 历史 DNS 记录、证书透明日志、邮件头没有泄露源站;
- 旧的 Nginx 入口没有继续监听公网。
测试源站直连:
curl -I http://你的VPS_IP
curl -kI https://你的VPS_IP
如果还能访问到网站,就说明源站还没真正收口。
| 对比项 | 普通橙云代理 | Cloudflare Tunnel |
|---|---|---|
| 是否需要公网入站 80/443 | 需要 | 不需要 |
| 是否隐藏源站 IP | 部分隐藏 | 更彻底,但仍要清理历史泄露 |
| 是否适合 NAT/家宽 | 不适合 | 适合 |
| 是否支持 Access | 支持 | 支持,体验更完整 |
| 排障复杂度 | 较低 | 略高 |
普通橙云已经能解决很多 CDN/WAF/缓存问题;Tunnel 更适合你想进一步缩小 VPS 暴露面,或者没有公网入站条件的场景。
发布服务前,至少检查:
- 本地服务
curl http://127.0.0.1:端口正常; - Cloudflare Tunnel connector 显示 Healthy;
- Public Hostname 指向正确本地端口;
- UFW 没把 SSH 锁死;
- VPS 公网 80/443 已关闭或不再返回业务页面;
- 后台域名已加 Cloudflare Access;
- Webhook 路径没有被 Access 误拦;
-
journalctl -u cloudflared没有持续错误; - 域名访问、直连 IP、移动网络都测试过。
这些情况要谨慎:
- 你需要完全控制 Nginx TLS 细节和证书链;
- 业务有大量大文件下载或特殊协议;
- 你不想把入口强依赖 Cloudflare;
- 你所在网络对 Cloudflare 出站连接不稳定;
- 你需要非 HTTP 协议但不想引入额外客户端或 Zero Trust 配置。
如果只是普通网站、管理后台、自托管工具、内部面板,Tunnel 的收益通常大于复杂度。
Cloudflare Tunnel 很适合 VPS 用户做三件事:隐藏源站 IP、减少公网入站端口、给后台服务加一层 Zero Trust 访问控制。
它的核心不是“让网站更快”,而是“让源站更少暴露”。如果你已经接入 Cloudflare,又担心源站被直连、后台被扫、家宽/NAT 没法开放端口,那么 Tunnel 是非常值得掌握的一套方案。
真正安全的做法是:Tunnel 发布服务,防火墙关闭不必要入站,后台用 Access 保护,日志持续观察。这样 VPS 才不是孤零零暴露在公网,而是放在 Cloudflare 边缘网络后面受控访问。