VPS 使用云隧道(Cloudflare Tunnel):无需开放端口即可安全暴露服务

开放防火墙端口以将 VPS 上的服务暴露到互联网,是传统的做法——但这带来了相当大的风险。每一个开放的端口都是攻击者潜在的入口。云隧道(Cloudflare Tunnel)通过从 VPS 到 Cloudflare 网络建立加密出站隧道来解决这一问题,让您无需开放任何入站端口。

什么是云隧道(Cloudflare Tunnel)?

云隧道(Cloudflare Tunnel)(前身为 Argo Tunnel)是一项零信任网络访问服务,可让您的 VPS 通过名为 cloudflared 的守护进程向 Cloudflare 网络发起出站连接。当用户请求您的服务时,流量经由 Cloudflare 边缘节点流入,再通过隧道返回您的 VPS——从不直接触及您的公共 IP。

这意味着您的 VPS 无需开放任何入站端口。防火墙可以 100% 阻止所有入站连接,大幅缩小攻击面。

云隧道(Cloudflare Tunnel)与直接端口转发的对比

注意:云隧道(Cloudflare Tunnel)在免费套餐中完全免费。开始使用前,您需要一个已将域名服务器指向 Cloudflare 的域名。

前置条件

在 Ubuntu VPS 上的分步安装教程

第一步:安装 cloudflared

# 下载适用于 Linux AMD64 的 cloudflared
curl -L --output cloudflared.deb \
  https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb

# 安装软件包
sudo dpkg -i cloudflared.deb

# 验证版本
cloudflared --version

第二步:向 Cloudflare 进行身份验证

# 此命令会输出一个 URL,请在浏览器中打开以完成授权
cloudflared tunnel login

在浏览器中打开该 URL,选择您要使用的域名,Cloudflare 随即会自动在 ~/.cloudflared/cert.pem 创建证书。

第三步:创建隧道

# 创建新隧道(名称可自定义)
cloudflared tunnel create my-vps-tunnel

# 列出现有隧道
cloudflared tunnel list

第四步:创建配置文件

nano ~/.cloudflared/config.yml

添加以下内容(将 YOUR-TUNNEL-ID 替换为第三步获得的 ID):

tunnel: YOUR-TUNNEL-ID
credentials-file: /root/.cloudflared/YOUR-TUNNEL-ID.json

ingress:
  - hostname: app.yourdomain.com
    service: http://localhost:3000
  - hostname: web.yourdomain.com
    service: http://localhost:80
  - service: http_status:404

第五步:创建 DNS 记录

# 创建指向隧道的 CNAME 记录
cloudflared tunnel route dns my-vps-tunnel app.yourdomain.com
cloudflared tunnel route dns my-vps-tunnel web.yourdomain.com

第六步:将隧道作为系统服务运行

# 将 cloudflared 安装为 systemd 服务
sudo cloudflared --config /root/.cloudflared/config.yml service install

# 启用并启动服务
sudo systemctl enable cloudflared
sudo systemctl start cloudflared

# 查看状态
sudo systemctl status cloudflared

cloudflared — 无需开放端口即可暴露 VPS 服务的核心原理

云隧道(Cloudflare Tunnel)的核心是运行在 VPS 上的 cloudflared 守护进程,它始终与 Cloudflare 边缘节点保持持久出站连接。该连接是双向的双向 TLS(mTLS)通道。当请求到达您的域名时,Cloudflare 通过已建立的连接将其推送到您的 VPS——因此 VPS 无需开放任何入站端口。这是一种"反向隧道":不是互联网主动连入您的服务器,而是服务器主动连接 Cloudflare。其结果是入站防火墙可以完全封闭。

以下是针对全新 AsiaGB Ubuntu VPS 的完整安装和创建流程,便于直接复制粘贴使用:

# 1) 安装 cloudflared(Ubuntu 20.04/22.04 AMD64)
curl -L --output cloudflared.deb \
  https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared.deb
cloudflared --version

# 2) 身份验证并授权您的域名(在浏览器中打开输出的 URL)
cloudflared tunnel login

# 3) 创建新隧道并列出隧道
cloudflared tunnel create my-vps-tunnel
cloudflared tunnel list

# 4) 记录隧道 ID 和凭据(.json)文件路径,用于 config.yml

完成第三步后,Cloudflare 会在 ~/.cloudflared/<TUNNEL-ID>.json 写入凭据文件——这是您隧道的密钥。切勿将其推送到公开的 Git 仓库或分享给他人:任何获得此文件的人都可以冒充您的隧道。

详细配置 config.yml 并设置 DNS 路由

config.yml 文件定义了哪个公共主机名对应哪个内部服务。ingress(入口规则)块从上到下依次读取,类似路由表,最后一条规则必须始终是兜底的 http_status:404——否则 cloudflared 在启动时会报错:

# ~/.cloudflared/config.yml
tunnel: YOUR-TUNNEL-ID
credentials-file: /root/.cloudflared/YOUR-TUNNEL-ID.json

ingress:
  # 运行在 3000 端口的 Node.js 应用
  - hostname: app.yourdomain.com
    service: http://localhost:3000
  # 运行在 80 端口的主网站
  - hostname: web.yourdomain.com
    service: http://localhost:80
  # 示例:内部 TLS 服务(跳过内部证书验证)
  - hostname: secure.yourdomain.com
    service: https://localhost:8443
    originRequest:
      noTLSVerify: true
  # 兜底规则 — 必须作为最后一条
  - service: http_status:404

运行前请使用 cloudflared tunnel ingress validate 验证语法以发现 YAML 错误,然后将每个公共主机名的 DNS 记录绑定到隧道——Cloudflare 会自动创建一条特殊的代理 CNAME:

# 先验证配置
cloudflared tunnel ingress validate

# 为每个公共主机名路由到隧道(自动创建 CNAME)
cloudflared tunnel route dns my-vps-tunnel app.yourdomain.com
cloudflared tunnel route dns my-vps-tunnel web.yourdomain.com
cloudflared tunnel route dns my-vps-tunnel secure.yourdomain.com

# 安装服务前先在前台运行以查看实时日志
cloudflared tunnel run my-vps-tunnel

如果页面仍无法加载,请检查终端日志中是否出现 Registered tunnel connection,并使用 ss -tlnp 确认内部服务(Node.js、Nginx 等)确实在配置的端口上监听。

将 cloudflared 作为持久 systemd 服务运行

前台测试通过后,将 cloudflared 配置为后台服务,利用 systemd 在每次重启时自动启动——这是 Ubuntu 上的标准做法:

# 安装为 systemd 服务(从指定路径读取配置)
sudo cloudflared --config /root/.cloudflared/config.yml service install

# 开机自启 + 立即启动
sudo systemctl enable cloudflared
sudo systemctl start cloudflared

# 查看状态 + 跟踪实时日志
sudo systemctl status cloudflared
sudo journalctl -u cloudflared -f

每次修改 config.yml 后,请记得运行 sudo systemctl restart cloudflared 使新配置生效。为保障 99% 在线率,请保持 systemctl enable 开启,使服务在重启或内核更新后自动恢复,并添加外部监控来监视该服务。

提示:如需高可用,可使用同一个隧道 ID 运行多个 cloudflared 实例(甚至跨多台 VPS)。Cloudflare 会自动对连接进行负载均衡,当一个实例宕机时,另一个实例会立即接管流量。

隧道的安全优势与最佳适用场景

团队从直接端口转发迁移到云隧道(Cloudflare Tunnel)的主要原因,是无需额外硬件投入即可立即获得安全升级:

云隧道(Cloudflare Tunnel)在 AsiaGB Ubuntu VPS 上的典型适用场景包括:

隧道配置完成后锁定 UFW 防火墙

隧道运行后,可以安全地阻断所有入站端口,仅保留 SSH 用于管理:

# 设置默认策略
sudo ufw default deny incoming
sudo ufw default allow outgoing

# 仅允许您的 IP 访问 SSH
sudo ufw allow from YOUR_IP to any port 22

# 启用 UFW
sudo ufw enable

# 查看规则
sudo ufw status verbose

安全提示:将 SSH 限制为仅您的 IP 地址(ufw allow from 1.2.3.4 to any port 22),可防止对管理界面的暴力破解攻击。

将 Cloudflare Access 与隧道结合使用

Cloudflare Access 在通过隧道暴露的服务前添加身份验证层。您可以要求用户通过 Google、GitHub 或邮箱登录,才能访问管理面板、Portainer 或控制台等内部工具。

常见问题解答(FAQ)

云隧道(Cloudflare Tunnel)真的免费吗?有隐藏费用吗?

云隧道(Cloudflare Tunnel)和 cloudflared 守护进程在 Cloudflare 免费套餐中完全免费——足以暴露网站及个人或中小企业服务。您只需拥有一个已将域名服务器指向 Cloudflare 的域名即可。部分高级功能(如大量 Access 用户)可能需要升级套餐,但本教程中的所有操作均无需任何费用。

使用隧道后,VPS 还需要开放 80/443 端口吗?

不需要。cloudflared 会主动向 Cloudflare 发起出站连接,因此您可以将 UFW 设置为完全 拒绝入站,只保留第 22 端口(SSH)用于管理。如需最高安全级别,甚至可以通过隧道暴露 SSH 并关闭对外的第 22 端口,实现零入站端口。

VPS 重启后隧道会自动恢复吗?

会。只要将 cloudflared 安装为 systemd 服务并执行 sudo systemctl enable cloudflared,systemd 就会在每次启动时自动启动该服务,无需手动操作,隧道在重启或内核更新后可自动恢复。

云隧道(Cloudflare Tunnel)与 VPN 或端口转发有何区别?

端口转发会直接在 VPS 上开放入站端口,将真实 IP 和端口暴露于攻击之下。传统 VPN 需要安装客户端并自行管理密钥。云隧道(Cloudflare Tunnel)仅使用出站连接:隐藏真实 IP、不开放任何入站端口,并在边缘节点享有 Cloudflare 的 WAF 和 DDoS 防护——用户只需访问您的普通域名,无需安装任何客户端。

立即获取安全 VPS

Linux VPS 最低 500 泰铢/月,配备完整 Root 权限、SSD 存储和独立 IP,数据中心位于泰国和新加坡。

查看 VPS 套餐

查看泰国VPS主机全部套餐 →