Cloudflare Tunnels 完全安装与内网穿透配置指南

Cloudflare Tunnels 完全安装与内网穿透配置指南

Cloudflare Tunnel 是 Cloudflare 提供的零信任网络访问方案,通过在本地运行一个轻量级 daemon(cloudflared),在内网服务和 Cloudflare 边缘之间建立加密隧道。无需公网 IP、无需开放端口、无需配置 NAT 或防火墙规则,就能把内网的 Web 服务、SSH、数据库等安全暴露出去。

本文将手把手教你从安装到配置的完整流程,覆盖 Linux、macOS、Docker 以及 Windows 平台,并分别演示 Web HTTP、SSH、TCP 服务穿透的实际操作。

一、安装 cloudflared

1. Debian / Ubuntu

curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 -o /usr/local/bin/cloudflared
chmod +x /usr/local/bin/cloudflared
cloudflared --version

如果用 ARM 架构的机器(如树莓派):

curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-arm64 -o /usr/local/bin/cloudflared
chmod +x /usr/local/bin/cloudflared

2. CentOS / RHEL / Fedora

cat <<'EOF' > /etc/yum.repos.d/cloudflared.repo
[cloudflared]
name=Cloudflared
baseurl=https://packages.cloudflare.com/cloudflared/rpm
enabled=1
gpgcheck=0
EOF
yum install cloudflared -y

3. macOS (Homebrew)

brew install cloudflared
cloudflared --version

4. Windows

从 GitHub Releases 页面下载最新 .msi 安装包:https://github.com/cloudflare/cloudflared/releases,双击运行安装即可。安装完成后在命令行输入 cloudflared --version 验证。

5. Docker 方式

docker run -d --name cloudflared --restart always \
  cloudflare/cloudflared:latest tunnel --no-autoupdate run --token <你的Token>

二、三种 Tunnel 创建方式对比

方式 适用场景 凭证管理 推荐度
Token 模式 简单场景,单个服务 Token 明文写在命令行或文件里 ⭐⭐⭐
Config 模式 多服务、生产环境 YAML 配置文件 + credentials.json ⭐⭐⭐⭐⭐
Connectors 模式 大规模部署、远程管理 cloudflared connect 命令连接代理 ⭐⭐⭐⭐

下面重点讲解 Token 模式(最简单快速)和 Config 模式(最灵活可靠)。

三、方案 A:Token 模式快速上手

适合只暴露一个服务、不想折腾配置文件的场景。

1. 在 Cloudflare Zero Trust 面板创建隧道

  1. 登录 Cloudflare Zero Trust Dashboard
  2. 左侧菜单选择 NetworksTunnels
  3. 点击 Create a tunnel,选择 Cloudflared 作为 connector
  4. 填写隧道名称(如 my-web-tunnel
  5. 点击 Save tunnel,然后切换到 Public Hostnames 标签页
  6. 添加一条路由规则:
    • Subdomain:填你想要的子域名,如 app
    • Domain:选择你的主域名
    • Service:选择 HTTP
    • URL:填内网服务地址,如 localhost:8080
  7. 点击 Save tunnel
  8. 最后点击 Install and run a connector,根据系统选择对应指令

如果是 Token 模式,安装命令会类似这样:

cloudflared tunnel --config ~/.cloudflared/config.yml install my-web-tunnel
cloudflared tunnel route dns my-web-tunnel app.example.com

但这种方法还是依赖配置文件。真正的纯 Token 模式不需要 config.yml——看下面的步骤。

2. 获取 Token 并直接启动

从 Zero Trust 面板 → Tunnels → 你的隧道 → Configure token 复制 Token,然后直接在终端运行:

cloudflared tunnel --no-autoupdate run --token eyJvIjoi...你的Token...abc123

就是这么简单!一个命令搞定。如果内网有多个服务要用不同的域名映射到不同端口,这种方式就不够用了,需要 Config 模式。

四、方案 B:Config 模式(生产环境推荐)

1. 认证登录

先让本机登录到 Cloudflare 账户:

cloudflared tunnel login

执行后会弹出一个浏览器窗口,要求你授权。授权完成后,cloudflared 会在 ~/.cloudflared/ 目录下生成一个 cert.pem 文件(这就是凭证)。

2. 创建隧道

cloudflared tunnel create my-web-tunnel

输出类似:

Tunnel credentials saved to /home/user/.cloudflared/xxx.json

记下这个 JSON 文件的路径和 Tunnel ID。你可以用以下命令查看所有隧道列表:

cloudflared tunnel list

3. 配置路由规则

创建或编辑 /home/user/.cloudflared/config.yml

tunnel: your-tunnel-id-here
credentials-file: /home/user/.cloudflared/your-tunnel-id.json

ingress:
  # 规则1:将 app.example.com 转发到本地 8080 端口的 Web 服务
  - hostname: app.example.com
    service: http://localhost:8080
  
  # 规则2:将 ssh.example.com 转发到本地 22 端口(SSH)
  - hostname: ssh.example.com
    service: ssh://localhost:22
  
  # 规则3:catch-all 兜底规则
  - service: http_status:404

注意最后的 catch-all 规则(http_status:404)是必须的,它会在没有匹配到任何 ingress 规则时返回 404,避免流量被丢弃。

添加 DNS 路由记录:

cloudflared tunnel route dns my-web-tunnel app.example.com
cloudflared tunnel route dns my-web-tunnel ssh.example.com

4. 启动 Tunnel

cloudflared tunnel --config ~/.cloudflared/config.yml run my-web-tunnel

看到输出中有多行 ConnectedHealthy 字样,说明隧道已成功建立。按 Ctrl+C 可以停止。

5. 设置为后台服务

5.1 systemd 方式

创建 service 文件:

[Unit]
Description=Cloudflared Tunnel
After=network-online.target
Wants=network-online.target

[Service]
Type=notify
ExecStart=/usr/local/bin/cloudflared tunnel --config /home/user/.cloudflared/config.yml run my-web-tunnel
Restart=on-failure
RestartSec=5
User=user
Group=user

[Install]
WantedBy=multi-user.target

保存为 /etc/systemd/system/cloudflared-tunnel.service,然后:

sudo systemctl daemon-reload
sudo systemctl enable cloudflared-tunnel
sudo systemctl start cloudflared-tunnel
sudo systemctl status cloudflared-tunnel

5.2 Docker Compose 方式

创建 docker-compose.yml

version: "3"
services:
  cloudflared:
    image: cloudflare/cloudflared:latest
    container_name: cloudflared
    restart: unless-stopped
    command: tunnel --no-autoupdate run --token eyJvIjoi...你的Token...abc123
    networks:
      - default

启动:

docker compose up -d
docker logs -f cloudflared

五、各种服务的穿透配置

1. HTTP/HTTPS Web 服务

ingress:
  - hostname: web.example.com
    service: http://localhost:3000
    originRequest:
      noTLSVerify: false
      connectTimeout: 10s
      tlsTimeout: 10s
      httpHostHeader: "localhost:3000"
      originServerName: "localhost"
  - service: http_status:404

可以通过 originRequest 自定义超时、是否跳过 TLS 验证、HTTP Host Header 等参数。

2. SSH 穿透

服务端(config.yml)

ingress:
  - hostname: ssh.myserver.com
    service: ssh://localhost:22
  - service: http_status:404

客户端连接

直接用浏览器访问,或者在本地电脑配置 SSH:

# 方法1:直接用 cloudflared 命令行连接
cloudflared access ssh --hostname ssh.myserver.com

# 方法2:配置 ~/.ssh/config
Host my-server
    HostName ssh.myserver.com
    User root
    ProxyCommand /usr/local/bin/cloudflared access ssh --hostname %h

然后可以直接 ssh my-server 连入。

3. TCP 非 HTTP 服务穿透

比如 MySQL(3306)、Redis(6379)等不支持 HTTP 的服务:

ingress:
  - hostname: db.example.com
    service: tcp://localhost:3306
  - service: http_status:404

或者用 hostname 格式不映射域名,直接用 Token 的方式:

# 隧道注册后,可以用以下方式绑定更多 TCP 端口而不需修改 config.yml
# 通过 Zero Trust 面板添加 TCP 路由规则

4. WebSocket 支持

WebSocket 天然支持,Cloudflare Tunnel 会自动检测并处理升级请求,不需要额外配置。如果你的应用跑在 localhost:8001

ingress:
  - hostname: ws.example.com
    service: http://localhost:8001
  - service: http_status:404

5. 反向代理本地其他服务

如果你的服务器本身就是一个反向代理(如 Nginx/Caddy),只想把所有流量统一转发给后端:

ingress:
  - hostname: site.example.com
    service: http://localhost:80
  - service: http_status:404

6. 多服务多域名

同一个隧道可以同时映射多个域名到不同内网服务:

ingress:
  # 前端
  - hostname: www.example.com
    service: http://localhost:3000
  
  # API
  - hostname: api.example.com
    service: http://localhost:8080
  
  # 后台管理
  - hostname: admin.example.com
    service: http://localhost:8081
  
  # SSH
  - hostname: ssh.example.com
    service: ssh://localhost:22
  
  # 兜底
  - service: http_status:404

六、高级配置与优化

1. 连接健康检查

config.yml 中配置:

tunnel: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
credentials-file: /home/user/.cloudflared/xxxx.json
metrics: :9000  # Prometheus 指标导出端口

ingress:
  - hostname: app.example.com
    service: http://localhost:8080
    originRequest:
      connectTimeout: 30s
      noHappyEyeballs: false
      keepAliveConnections: 100
      keepAliveTimeout: 90s
      tcpKeepAlive: 30s

2. 访问控制(Zero Trust Access)

可以为隧道添加访问策略,只有经过认证的用户才能访问:

在 Zero Trust 面板 → Access → Applications 中创建应用,关联到你的隧道域名,然后设置规则:

  • 允许特定邮箱域名
  • 允许特定群组
  • 启用 MFA 验证

配置好 Access 后,访问 app.example.com 会被自动跳转到 Cloudflare 登录页面,用户认证成功后才会进入后端服务。

3. 日志调试

# 查看实时日志
journalctl -u cloudflared-tunnel -f

# 手动测试 ingress 规则
cloudflared tunnel ingress test --url https://app.example.com

4. 常见问题排查

问题 可能原因 解决方法
Tunnel 连接后很快断开 网络不稳定或防火墙限制 检查出口网络连接,确认 7844/20000 端口未受阻
DNS 解析正常但无法访问 ingress 规则错误或服务未启动 cloudflared tunnel ingress test 测试,检查目标服务是否监听
SSL 证书报错 域名未正确绑定隧道 确保域名 CNAME 指向 .trycloudflare.com
登录失败 cert.pem 权限或过期 重新执行 cloudflared tunnel login

七、总结

  • 快速试用:直接用 --token 模式一行命令启动。
  • 生产部署:推荐 Config 模式 + systemd 托管,配合 Cloudflare Access 做身份验证。
  • 批量管理:考虑 Connectors 模式或之前提到的脚本自动化方案。

Cloudflare Tunnel 最大的优势就是安全——你的内网服务完全不出现在公网面上,不需要开任何防火墙规则。所有流量都经过 Cloudflare 边缘节点加密传输,配合 Access 策略可以做到细粒度的访问控制。

不管你是要穿透一个个人博客、内网管理系统、SSH 跳板机,还是各种私有协议的服务,Cloudflare Tunnel 都能胜任。

本文由 BOSH 的博客助手 HerMes 整理 🔧

原文链接:[本地上传]