Cloudflare Tunnel(原 Argo Tunnel):内网穿透神器,安全高效连接您的服务
在当今的网络环境中,将本地或私有网络中的服务(如网站、SSH服务器、远程桌面等)安全、稳定地暴露到公网上,常常是一个令人头疼的问题。传统的解决方案通常涉及购买公网IP、配置端口转发、设置动态DNS、维护防火墙规则,甚至需要应对DDoS攻击和恶意扫描。这些方法不仅操作复杂、维护成本高,而且存在安全风险。
幸运的是,Cloudflare 提供了一个名为 Cloudflare Tunnel(之前广为人知的名字是 Argo Tunnel)的强大工具,它彻底改变了内网穿透的方式。Cloudflare Tunnel 允许您将您的本地服务通过一条加密的出站连接安全地连接到 Cloudflare 的全球网络边缘,无需开放任何入站端口,无需公网IP,即可让用户通过您绑定的域名访问您的服务。
本文将详细介绍 Cloudflare Tunnel 的概念、优势、安装、配置以及多种使用场景,帮助您轻松掌握这个强大的内网穿透神器。
什么是 Cloudflare Tunnel?
Cloudflare Tunnel 是一项服务,它通过在您的本地服务器上运行一个轻量级的守护进程 cloudflared
,与 Cloudflare 的全球边缘网络建立一条安全的、持久的、出站的连接隧道。所有流向您的服务的流量都首先到达 Cloudflare 的边缘网络,然后通过这条加密隧道被安全地转发到您的本地服务器上运行的 cloudflared
进程,最后由 cloudflared
将请求转发给您本地的服务(如 Nginx, Apache, Node.js 应用, SSH 服务等)。
核心理念:
- 出站连接:
cloudflared
进程主动发起连接到 Cloudflare 的边缘,而不是等待入站连接。这意味着您不需要在防火墙上打开任何入站端口。 - 安全隧道: 隧道是加密的,确保数据传输的安全性。
- 域名绑定: 您将您的域名解析到 Cloudflare,Cloudflare 根据配置将特定域名的请求通过隧道转发到您的本地服务。
- 无公网IP需求: 您的本地服务器无需拥有公网IP地址。
Cloudflare Tunnel 的优势
-
极高的安全性:
- 消除入站风险: 由于无需开放入站端口,您的服务器不会直接暴露在公网上,大大降低了被扫描、攻击的风险。
- 默认启用 Cloudflare 安全功能: 您的服务受益于 Cloudflare 的WAF(Web应用防火墙)、DDoS防护、SSL/TLS加密等安全特性。
- 基于零信任原则: 结合 Cloudflare Access 等功能,可以实现基于身份和上下文的访问控制,而不是简单的网络层访问控制。
-
简单易用:
- 无需复杂网络配置: 告别繁琐的端口转发、动态DNS设置。
- 配置简单: 主要通过一个 YAML 配置文件来定义隧道规则。
- 跨平台支持:
cloudflared
守护进程支持 Linux、Windows、macOS、Docker 等多种平台。
-
高性能与可靠性:
- 全球加速: 利用 Cloudflare 遍布全球的边缘网络,用户可以从离他们最近的节点访问您的服务,降低延迟。
- 负载均衡 (Premium Feature): 可以将同一个隧道运行在多个服务器上,Cloudflare 会自动进行负载均衡,提高可用性。
- 健康检查: 可以配置对源站服务的健康检查,自动切换到健康的实例。
-
无需公网IP与动态DNS: 完美解决了家用网络或只分配了内网IP/动态公网IP用户的服务暴露问题。
-
支持多种协议: 不仅限于 HTTP/HTTPS,还支持 SSH、RDP、TCP 等多种协议。
使用 Cloudflare Tunnel 的前提条件
在开始之前,您需要准备好以下几项:
- 一个 Cloudflare 账户: 如果没有,请前往 https://dash.cloudflare.com/sign-up 注册一个免费账户。
- 一个域名: 您需要有一个自己的域名,并且该域名已经在 Cloudflare 中激活并管理 DNS。
- 一个需要暴露到公网的服务: 比如运行在您本地服务器 IP 地址(通常是
127.0.0.1
或内网 IP)和特定端口上的 Web 服务器、SSH 服务等。 - 一台运行
cloudflared
守护进程的机器: 这台机器需要能够访问到您的本地服务,并且能够连接到互联网(出站连接)。通常就是运行服务的同一台机器或同个内网的另一台机器。
Cloudflare Tunnel 安装教程
cloudflared
是 Cloudflare Tunnel 的核心组件,需要在您的本地机器上安装它。Cloudflare 提供了多种安装方式,覆盖主流操作系统。
1. Linux / macOS 安装
这是最常见的安装方式,通常通过包管理器或官方脚本进行。
使用官方安装脚本 (推荐):
打开终端,运行以下命令:
bash
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
可执行文件到/usr/local/bin
目录,并赋予执行权限。/usr/local/bin
通常已经在系统的 PATH 环境变量中,方便直接调用。 - 如果您使用的是 ARM 架构的 Linux (如树莓派),请将
cloudflared-linux-amd64
替换为cloudflared-linux-arm64
或cloudflared-linux-arm
。
使用包管理器 (特定发行版):
-
Debian / Ubuntu:
bash
curl -L https://pkg.cloudflare.com/cloudflare-release.oxy > cloudflare-release.deb
sudo dpkg -i cloudflare-release.deb
rm cloudflare-release.deb
sudo apt-get update
sudo apt-get install cloudflared
这将添加 Cloudflare 的 APT 仓库并安装cloudflared
。 -
RHEL / CentOS:
bash
curl -L https://pkg.cloudflare.com/cloudflare-release.rpm > cloudflare-release.rpm
sudo rpm -ivh cloudflare-release.rpm
rm cloudflare-release.rpm
sudo yum update
sudo yum install cloudflared
这将添加 Cloudflare 的 YUM 仓库并安装cloudflared
。 -
macOS (使用 Homebrew):
bash
brew install cloudflare/cloudflare/cloudflared
2. Windows 安装
从 Cloudflare 官方 GitHub Release 页面下载最新版本的 cloudflared-windows-amd64.exe
文件:
https://github.com/cloudflare/cloudflared/releases
- 下载后,将
cloudflared-windows-amd64.exe
重命名为cloudflared.exe
。 - 将其放到一个您方便管理的目录,例如
C:\Program Files\cloudflared
。 - 推荐: 将该目录添加到系统的环境变量
Path
中,这样您就可以在任何地方打开命令提示符或 PowerShell 直接运行cloudflared
命令了。
3. Docker 安装
如果您习惯使用 Docker,Cloudflare 也提供了官方 cloudflared
镜像。
bash
docker pull cloudflare/cloudflared
之后运行 cloudflared
命令时,您需要通过 docker run cloudflare/cloudflared <command>
的方式来执行。配置和使用方法与直接安装类似,但需要考虑卷挂载(Volume Mounting)来保存配置文件和证书。
验证安装:
安装完成后,打开新的终端或命令提示符,运行:
bash
cloudflared --version
如果看到版本号输出,说明安装成功。
连接 Cloudflare 账户 (认证)
在运行 cloudflared
创建和管理隧道之前,您需要将其与您的 Cloudflare 账户关联起来。
运行以下命令:
bash
cloudflared tunnel login
执行此命令后,cloudflared
会在您的终端中输出一个 URL,并提示您在浏览器中打开这个 URL。
“`
Please open the following URL and login with your Cloudflare account:
https://dash.cloudflare.com/argotunnel?callback=https%3A%2F%2Flogin.cloudflareaccess.com%2F…
You have 5 minutes to complete the login.
“`
将这个 URL 复制到浏览器中打开。浏览器会引导您登录您的 Cloudflare 账户,并要求您授权 cloudflared
访问您账户下的域名。选择您想要使用 Tunnel 的域名,点击 “Authorize”(授权)。
授权成功后,浏览器会显示一个成功页面,并且 cloudflared
命令也会在终端中输出类似以下信息:
You have successfully logged in.
If you are running cloudflared non-interactively, you will need to use --cred-file or GALLARY_AUTH to provide credentials.
同时,cloudflared
会在默认配置目录下创建一个名为 cert.pem
的文件。
- Linux/macOS:
~/.cloudflared/cert.pem
- Windows:
%USERPROFILE%\.cloudflared\cert.pem
这个 cert.pem
文件包含了认证信息,允许 cloudflared
代表您的账户创建和管理隧道。请妥善保管此文件,不要泄露。 今后所有的隧道操作都将使用这个文件进行认证,除非您删除了它需要重新登录。
创建 Cloudflare Tunnel
登录成功后,您就可以创建隧道了。一个隧道是一个逻辑上的概念,由一个唯一的 UUID 标识。
运行创建命令:
bash
cloudflared tunnel create <隧道名称>
请将 <隧道名称>
替换为您想为隧道起的一个易于识别的名字,例如 my-web-tunnel
或 ssh-access
。
执行命令后,您会看到类似如下的输出:
“`
Tunnel credentials file written to /home/user/.cloudflared/
You can now copy this file to your origin service machine(s) and run:
cloudflared tunnel run
Tunnel <隧道名称>
“`
这条命令做了几件事:
- 在默认配置目录下创建了一个与该隧道关联的 JSON 文件,文件名为
<UUID>.json
。这个文件包含了该隧道的密钥信息,cloudflared
进程需要这个文件来连接到特定的隧道。 - 输出了该隧道的 UUID(Universally Unique Identifier)。这是一个32位的十六进制字符串,是隧道的唯一标识符。
- 提示了如何运行该隧道。
重要: 您应该将生成的 <UUID>.json
文件妥善保管。如果您的 cloudflared
进程运行在另一台机器上,您需要将这个 JSON 文件拷贝到那台机器的 ~/.cloudflared/
或 %USERPROFILE%\.cloudflared\
目录下(或您指定给 cloudflared
的目录)。
配置 Cloudflare Tunnel
虽然可以直接在 cloudflared tunnel run
命令后面跟参数来指定服务的地址和端口,但更推荐的方式是使用配置文件 (config.yml
)。这样可以更清晰地定义多个服务的映射规则,并且方便管理。
默认的配置文件路径是 ~/.cloudflared/config.yml
(Linux/macOS) 或 %USERPROFILE%\.cloudflared\config.yml
(Windows)。如果文件不存在,您可以手动创建它。
一个典型的 config.yml
文件结构如下:
“`yaml
指定要运行的隧道的 UUID
tunnel:
指定隧道的 credentials 文件路径
如果 credentials 文件就在 config.yml 同目录下,可以只写文件名
credentials-file: /home/user/.cloudflared/
ingress 规则定义了 Cloudflare 边缘收到请求后如何转发到本地服务
ingress:
# 规则 1:匹配特定的域名,转发到本地 Web 服务
– hostname: your-app.yourdomain.com # 替换为您实际的域名
service: http://localhost:8000 # 替换为您本地 Web 服务的地址和端口
# 可选的 originRequest 配置,例如跳过 TLS 验证
# originRequest:
# noTLSVerify: true
# 规则 2:匹配另一个域名或路径,转发到另一个本地服务
– hostname: ssh.yourdomain.com # 替换为您实际的域名
service: ssh://localhost:22 # 转发到本地的 SSH 服务
# 规则 3:更一般的匹配,如果前面的规则都不匹配,则使用此规则
– service: http_status:404 # 如果没有任何规则匹配,返回 404 错误
可选:配置日志输出
loglevel: info
logfile: /var/log/cloudflared.log
“`
配置文件详解:
tunnel
: 必填项,指定该配置文件用于哪个隧道。值是您创建隧道时获得的 UUID。credentials-file
: 必填项,指定隧道的 JSON 凭证文件路径。cloudflared
需要这个文件来验证身份并连接到隧道。ingress
: 定义一系列的规则,按顺序匹配传入的请求。- 每个规则由
hostname
和service
组成。 hostname
: (可选) 匹配请求的主机名。如果省略,则匹配所有主机名或路径。path
: (可选) 匹配请求的 URL 路径。例如/api/*
。service
: 必填项,指定请求应该被转发到哪个本地服务。格式通常是<protocol>://<address>:<port>
。http://localhost:8000
: 转发到本地的 HTTP 服务。https://localhost:8443
: 转发到本地的 HTTPS 服务 (如果您本地服务已经配置了 HTTPS)。ssh://localhost:22
: 转发到本地的 SSH 服务。tcp://localhost:3389
: 转发到本地的 TCP 服务 (如 RDP 远程桌面)。unix:///path/to/socket
: 转发到本地的 Unix Socket。http_status:<code>
: 不转发请求,直接返回指定的 HTTP 状态码(如http_status:404
)。通常作为最后一条规则,处理所有未匹配的请求。
originRequest
: (可选) 配置与源站服务通信时的行为。例如noTLSVerify: true
可以让cloudflared
在连接到本地使用自签名证书的 HTTPS 服务时跳过证书验证(不推荐在生产环境使用)。
- 每个规则由
- 规则顺序很重要:
cloudflared
会从上到下依次检查ingress
规则。一旦某个规则匹配成功,请求就会被转发到对应的服务,后续规则将被忽略。因此,更具体的规则(如包含hostname
和path
)应该放在前面,而更通用的规则(如只包含service: http_status:404
)应该放在最后。
创建或修改完 config.yml
文件后,您可以使用以下命令验证其语法是否正确:
bash
cloudflared tunnel validate
将域名指向隧道
创建了隧道并配置了 config.yml
文件后,您还需要告诉 Cloudflare 如何将您域名的流量导向这个隧道。这通过在 Cloudflare DNS 中创建一个 CNAME 记录来完成。
使用以下命令为您的主机名创建 DNS 记录并将其指向您的隧道:
bash
cloudflared tunnel route dns <UUID> <hostname>
将 <UUID>
替换为您隧道的 UUID,将 <hostname>
替换为您希望通过该隧道访问服务的主机名(例如 your-app.yourdomain.com
)。
执行此命令后,cloudflared
会自动在您的 Cloudflare DNS 中为 <hostname>
添加一条 CNAME 记录,指向 <UUID>.cfargotunnel.com
。这个特殊的 CNAME 目标告诉 Cloudflare 的边缘网络,将发送到 <hostname>
的流量通过您的隧道转发。
注意: 如果您之前已经手动创建了该主机名的 DNS 记录,此命令可能会报错。您可以先在 Cloudflare DNS 页面删除旧记录,再运行此命令。
您也可以手动创建 CNAME 记录:在 Cloudflare DNS 页面,添加一条 CNAME 记录,名称为您的主机名(例如 your-app
),目标为 <UUID>.cfargotunnel.com
。
运行 Cloudflare Tunnel
一切准备就绪后,您就可以启动 cloudflared
守护进程来建立并维护隧道连接了。
手动运行(测试用):
bash
cloudflared tunnel run <UUID>
或者,如果您已经创建了 config.yml
文件并且其中指定了 tunnel
和 credentials-file
,您可以在 config.yml
所在的目录下运行:
bash
cloudflared tunnel run
cloudflared
将会读取 config.yml
文件,连接到 Cloudflare 边缘,并根据 ingress
规则开始监听来自 Cloudflare 的请求,然后转发到您本地的服务。
此时,您应该可以在终端中看到 cloudflared
的运行日志,显示隧道已经连接成功。
重要: 手动运行的方式会在关闭终端后停止。为了让隧道在服务器重启后依然运行,您需要将其安装为系统服务。
将 Cloudflare Tunnel 安装为系统服务 (生产环境推荐)
为了确保 cloudflared
进程持久运行且能在服务器启动时自动启动,建议将其安装为系统服务。cloudflared
命令提供了方便的服务安装功能。
1. Linux (使用 systemd):
首先,确保您已经创建了 config.yml
文件,并且该文件位于 ~/.cloudflared/config.yml
(或其他您指定的路径,如果使用其他路径,后面安装服务时需要指定)。同时,确保 <UUID>.json
凭证文件也在正确的位置。
运行安装服务命令:
bash
sudo cloudflared tunnel service install
或者,如果您想指定配置文件路径或其他的运行参数:
bash
sudo cloudflared tunnel service install --config /path/to/your/config.yml --origincert /path/to/your/cert.pem --credential-file /path/to/your/<UUID>.json --systemd-unit cloudflared-my-tunnel # cloudflared-my-tunnel 是服务单元名称,可选
通常情况下,如果 config.yml 在标准位置,简单的 sudo cloudflared tunnel service install
就足够了。
安装成功后,cloudflared
会创建一个 systemd service unit 文件(通常在 /etc/systemd/system/cloudflared.service
或类似的路径)。
现在,您可以启动并启用该服务:
bash
sudo systemctl start cloudflared
sudo systemctl enable cloudflared # 设置开机自启
检查服务状态和日志:
bash
sudo systemctl status cloudflared
sudo journalctl -u cloudflared --follow
2. Windows (使用 Windows Service):
确保您已经将 cloudflared.exe
添加到 PATH 或在安装服务时指定其完整路径。创建 config.yml
和 <UUID>.json
文件,通常位于 %USERPROFILE%\.cloudflared\
。
打开管理员权限的命令提示符或 PowerShell。
运行安装服务命令:
cmd
cloudflared tunnel service install
或者指定配置文件路径:
cmd
cloudflared tunnel service install --config C:\Users\YourUser\.cloudflared\config.yml
安装成功后,您可以在 Windows 的“服务”管理器(services.msc
)中找到名为 “cloudflared” 的服务。
启动服务:
cmd
net start cloudflared
停止服务:
cmd
net stop cloudflared
服务的启动类型通常默认是“自动”,这意味着它会在系统启动时自动运行。您也可以在服务管理器中手动更改其启动类型。
查看服务日志通常需要检查 Windows 事件查看器。
常见使用场景示例
1. 暴露本地 Web 服务器 (HTTP/HTTPS)
假设您在本地机器的 8000 端口运行了一个 Web 服务器(如 Python 的 simple HTTP server, Node.js 应用等),希望通过 my-web.yourdomain.com
访问它。
-
config.yml
:yaml
tunnel: <UUID>
credentials-file: <UUID>.json # 假设文件在同目录下
ingress:
- hostname: my-web.yourdomain.com
service: http://localhost:8000
- service: http_status:404 -
运行
cloudflared tunnel route dns <UUID> my-web.yourdomain.com
。 - 将
cloudflared
安装为服务并启动。
现在,访问 https://my-web.yourdomain.com
(Cloudflare 默认会提供 SSL 加密)即可访问到您本地 8000 端口的服务。
2. 暴露本地 SSH 服务
如果您想通过 SSH 连接到您的本地机器,但没有公网 IP 或不想开放 22 端口。
-
config.yml
:yaml
tunnel: <UUID>
credentials-file: <UUID>.json
ingress:
- hostname: ssh.yourdomain.com
service: ssh://localhost:22
- service: http_status:404 -
运行
cloudflared tunnel route dns <UUID> ssh.yourdomain.com
。 - 将
cloudflared
安装为服务并启动。
现在,您可以使用支持 Cloudflare Tunnel 的 SSH 客户端(或通过 cloudflared access ssh
命令,这涉及到 Cloudflare Access,更高级)连接到 ssh.yourdomain.com
。或者更简单地,直接使用 cloudflared ssh ssh.yourdomain.com
命令进行连接。
3. 暴露多个服务
您可以在同一个 config.yml
文件中定义多个 ingress 规则,通过不同的主机名或路径来访问不同的本地服务。
-
config.yml
:yaml
tunnel: <UUID>
credentials-file: <UUID>.json
ingress:
- hostname: blog.yourdomain.com
service: http://localhost:2368 # Ghost 博客服务
- hostname: dashboard.yourdomain.com
service: http://localhost:8080 # Dashboard 服务
- hostname: files.yourdomain.com
path: /docs/* # 仅转发 /docs 路径下的请求
service: http://localhost:9000
- service: http_status:404 # 所有未匹配的请求返回 404 -
为
blog.yourdomain.com
,dashboard.yourdomain.com
,files.yourdomain.com
分别运行cloudflared tunnel route dns
命令。 - 将
cloudflared
安装为服务并启动。
这样您就可以通过不同的子域名访问不同的本地服务了。
管理 Cloudflare Tunnel
您可以使用 cloudflared tunnel
子命令来管理您的隧道。
-
列出所有隧道:
bash
cloudflared tunnel list
这将显示您账户下通过cloudflared tunnel create
创建的所有隧道及其 UUID 和状态。 -
删除隧道:
bash
cloudflared tunnel delete <UUID 或 隧道名称>
这将删除 Cloudflare 边缘的隧道配置。注意: 这并不会停止本地正在运行的cloudflared
进程,也不会删除本地的<UUID>.json
凭证文件。您需要手动停止并卸载服务,并删除相应的文件。 -
清理孤立的凭证文件:
bash
cloudflared tunnel cleanup
这个命令会检查本地的.json
凭证文件,并尝试删除那些不再对应任何已存在隧道的无效文件。 -
查看隧道状态:
bash
cloudflared tunnel status <UUID 或 隧道名称>
显示特定隧道的详细状态信息。
故障排除
如果在配置和使用 Cloudflare Tunnel 时遇到问题,可以从以下几个方面着手排查:
- 检查
cloudflared
进程状态: 确保cloudflared
服务正在运行。- Linux:
sudo systemctl status cloudflared
或sudo journalctl -u cloudflared --follow
查看日志。 - Windows: 在服务管理器中查看服务状态,或检查 Windows 事件查看器中的应用程序日志。
- Linux:
- 检查
config.yml
语法: 使用cloudflared tunnel validate
命令验证配置文件。 - 检查
<UUID>.json
凭证文件: 确保config.yml
中指定的credentials-file
路径正确,并且该文件存在且权限正确。 - 检查本地服务是否正常运行: 确保您在
config.yml
中配置的本地服务地址(如localhost:8000
)确实有服务在监听该端口,并且该服务在本地是可访问的。可以在运行cloudflared
的机器上使用curl http://localhost:8000
等命令测试。 - 检查防火墙: 确保运行
cloudflared
的机器的防火墙允许出站连接到 Cloudflare 的网络(通常是 7844 端口,但cloudflared
会自动发现可用的端口和协议)。同时,确保防火墙允许cloudflared
进程访问您本地的服务端口(如允许cloudflared
进程访问localhost:8000
或localhost:22
)。 - 检查 Cloudflare DNS 记录: 确保您要访问的主机名(例如
my-web.yourdomain.com
)在 Cloudflare DNS 中有正确的 CNAME 记录,指向<UUID>.cfargotunnel.com
。 - 网络连通性: 确保运行
cloudflared
的机器能够正常访问互联网。 - 查看 Cloudflare Dashboard: 在 Cloudflare Dashboard 中,进入您的域名设置,找到“Zero Trust”(可能需要先开启),然后在“Networks”->“Tunnels”下查看您的隧道状态。这里可以直观地看到隧道的健康状况和连接数。
总结
Cloudflare Tunnel (Argo Tunnel) 是一个功能强大且易于使用的内网穿透解决方案。通过建立安全的出站隧道,它允许您将本地服务安全、高效地暴露到公网上,无需公网IP,无需复杂的端口转发,同时还能享受到 Cloudflare 提供的各种安全和性能优势。无论是开发者在本地搭建演示环境,还是小型企业或个人用户需要暴露内部服务,Cloudflare Tunnel 都是一个值得考虑的优秀选择。
掌握 cloudflared
命令的使用,理解 config.yml
配置文件的结构,并将其作为系统服务运行,您就能轻松地利用 Cloudflare Tunnel 构建属于您自己的安全内网穿透体系。
希望这篇详细的教程能帮助您顺利安装、配置和使用 Cloudflare Tunnel!