Cloudflare Tunnel + SSH 内网穿透指南
本文介绍如何通过 Cloudflare Tunnel 和 cloudflared 服务,从公网任意位置安全地建立 SSH 连接。以下内容以「处于公网的笔记本电脑和处于内网的树莓派」为例。此方案无需公网 IP、端口映射或动态 DNS,只需要一个绑定了 Cloudflare Tunnel 的域名。
🚩前提条件
- 一个已注册并接入 Cloudflare 的域名(如
hoigin.cn) - 一台运行 Raspberry Pi OS 的树莓派(内网环境)
- 一台 Windows 笔记本(用于发起 SSH 连接)
🚇步骤一:在树莓派上配置 Cloudflare Tunnel
1. 安装 cloudflared
为了使用 Cloudflare 提供的内网穿透服务,首先要在树莓派上安装可以向内网穿透隧道收发数据的客户端 Cloudflared。
1
2
3
4
5
6
7
8
9
10
11
12
13
# 进入用户目录
cd ~
# 下载适用于树莓派 64 位系统的 .deb 包
wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-arm64.deb
# 安装
# -i 参数表示 install
sudo dpkg -i cloudflared-linux-arm64.deb
# 验证安装
cloudflared --version
# 输出类似:cloudflared version 2025.x.x
2. 登录并创建隧道
安装成功后,用以下命令在 Cloudflared 客户端登录账号。
1
2
# 浏览器授权,生成 cert.pem
cloudflared tunnel login
- 若树莓派有图形界面:自动打开浏览器,登录 Cloudflare
- 若无图形界面:复制终端给出的 URL 到电脑浏览器完成授权
- 成功后会在以下路径生成认证文件:
~/.cloudflared/cert.pem
接着,使用以下命令创建一条名为 raspberrypi-tunnel 的隧道。
1
cloudflared tunnel create raspberrypi-tunnel
创建成功后,此隧道的凭据文件将保存为 ~/.cloudflared/<UUID>.json ,记住此 <UUID> ,配置文件中需要用到。
3. 配置隧道路由
1
cloudflared tunnel route dns raspberrypi-tunnel ssh.hoigin.cn
此命令在 Cloudflare DNS 中创建一条 Proxied CNAME 记录,将 ssh.hoigin.cn 绑定到隧道。接下来可以登录 Cloudflare 官网,点击「Cloudflare 控制台 - DNS - 记录」进行查看。
Note
CNAME、A 和 AAAA 是 DNS(Domain Name System),即域名系统中常见的记录类型,DNS 会根据记录类型将域名解析为 IP 地址或其他域名。常见的几种记录类型及 DNS 的处理方式如下表所示。
| 记录类型 | 全称 / 含义 | DNS 的处理方式 |
|---|---|---|
| A | Address Record | 域名 → IPv4 地址 |
| AAAA | IPv6 Address Record | 域名 → IPv6 地址 |
| CNAME | Canonical Name Record | 域名 → 另一个域名(别名) |
| MX | Mail Exchange Record | 指定接收邮件的邮件服务器 |
| NS | Name Server Record | 指定该域名由哪些 DNS 服务器解析 |
在标准 DNS 语义中,这一操作表示 ssh.hoigin.cn 这个域名的别名是另一个域名 <UUID>.cfargotunnel.com ,当有用户查询 hoigin.cn 这个域名的时候,DNS 解析服务器就会去查询 <UUID>.cfargotunnel.com 这个域名的 IP 地址。但是,虽然这两个域名的关系在形式上是 CNAME,但 <UUID>.cfargotunnel.com 并不真的存在于公共 DNS 中,它只是 Cloudflare 内部用于标识隧道的一个逻辑端点名称。Cloudflare 看到它 CNAME 指向一个 .cfargotunnel.com 域名,就不会继续向外递归查询这个 CNAME 的 IP,而是直接返回 Cloudflare 自己的边缘 IP 地址,同时在内部标记这个请求属于隧道 <UUID> ,并查找是否有活跃的 Cloudflared 连接(来自树莓派),查询到有之后就通过已建立的加密隧道将 SSH 连接转发至用户端。
总之,到这一步就把内网穿透隧道和域名关联好了。
Tip
边缘节点(Edge Node),也称为接入点(Point of Presence,PoP),是在全球部署的服务器节点,用于就近处理用户请求。在现代互联网架构中是提升网站性能与安全的关键基础设施。截至 2025 年,Cloudflare 在超过 120 个国家和地区运营着 300 多个边缘节点,构成一个分布式的安全与加速网络。当用户访问使用 Cloudflare 的网站或通过 Tunnel 暴露的内网服务时,流量首先到达离用户最近的边缘节点,再由它负责安全过滤、缓存或通过加密隧道转发至源站。这种架构既提升了访问速度,又隐藏了真实服务器位置,增强了安全性。
4. 创建隧道配置文件
接下来使用前面记住的 <UUID> 来创建配置文件,放置在 ~/.cloudflared/config.yml 路径里,内容如下:
1
2
3
4
5
6
tunnel: <UUID> # 替换为实际 UUID(不含 .json 后缀)
credentials-file: /home/pi/.cloudflared/<UUID>.json # 替换为实际 UUID
ingress:
- hostname: ssh.hoigin.cn # SSH连接用的域名
service: tcp://localhost:22 # 树莓派上的cloudflared负责转发至22端口,即SSH默认端口
- service: http_status:404 # 未匹配请求返回 404
5. 以系统服务运行隧道
在终端输入以下命令,在 systemd/system 路径下创建一项名为 cloudflared.service 的后台服务。
1
sudo nano /etc/systemd/system/cloudflared.service
打开 cloudflared.service 文件,写入这项后台服务的配置,如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
[Unit]
; 服务的简要描述,显示在 systemctl status 等命令中
Description=Cloudflare Tunnel for hoigin.cn
; 指定该服务在网络已就绪后再启动,确保 cloudflared 能正常联网
After=network.target
[Service]
; Type=exec 表示主进程就是 ExecStart 启动的程序(推荐用于 cloudflared)
Type=exec
; 以普通用户 'pi' 身份运行服务,避免使用 root 提高安全性
User=pi
; 启动命令:运行名为 raspberrypi-tunnel 的 Cloudflare 隧道
; 注意:cloudflared 会自动读取 ~/.cloudflared/ 下的配置和凭据
ExecStart=/usr/bin/cloudflared tunnel run raspberrypi-tunnel
; 若服务异常退出(非零状态),则自动重启
Restart=on-failure
; 重启前等待 5 秒,避免频繁崩溃导致资源浪费
RestartSec=5
; 终止服务时仅杀死主进程(cloudflared),不杀其子进程(实际无子进程,此设置更安全)
KillMode=process
[Install]
; 设置服务启用(systemctl enable)后,在 multi-user.target(即常规多用户模式)下自动启动
WantedBy=multi-user.target
写入保存好之后,在终端启用服务即可。
1
2
3
4
5
6
7
8
9
10
11
# 重新加载 systemd 配置文件
sudo systemctl daemon-reload
# 设置服务开机自启动
sudo systemctl enable cloudflared
# 启动服务
sudo systemctl start cloudflared
# 检查服务是否正常运行
systemctl status cloudflared
🛠️步骤二:在笔记本上配置客户端
在 Windows Powershell 中配置
1. 安装 cloudflared
以管理员身份打开 PowerShell,运行:
1
winget install Cloudflare.cloudflared
2. 登录 Cloudflare 账户
1
cloudflared login
浏览器会自动打开,完成授权后生成 %USERPROFILE%\.cloudflared\cert.pem(生成的 cert.pem 文件有可能直接下载到默认文件夹,需要手动复制粘贴到这个路径)。
3. 生成 SSH 配置
1
cloudflared access ssh-config --hostname ssh.hoigin.cn
输出类似:
1
2
3
Host ssh.hoigin.cn
ProxyCommand C:\Users\ASUS\AppData\Local\Microsoft\WinGet\Packages\Cloudflare.cloudflared_...\cloudflared.exe access ssh --hostname %h
User pi
4. 写入 SSH 配置文件
编辑 C:\Users\ASUS\.ssh\config,添加上述内容。
在 Linux Shell 中配置
1. 安装 cloudflared
安装流程与在服务器端的一样,如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
# 进入用户目录
cd ~
# 下载适用于树莓派 64 位系统的 .deb 包
wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-arm64.deb
# 安装
# -i 参数表示 install
sudo dpkg -i cloudflared-linux-arm64.deb
# 验证安装
cloudflared --version
# 输出类似:cloudflared version 2025.x.x
2. 登录 Cloudflare 账户
1
cloudflared login
浏览器会自动打开,完成授权后生成 cert.pem 文件,接着需要手动复制粘贴到 ~/.cloudflared/cert.pem 这个位置。接着,为了让 cert.pem 文件中的私钥不被其他用户读取,需要对此文件设置权限,如下所示:
1
chmod 600 ~/.cloudflared/cert.pem
运行测试命令,验证 cloudflared 是否能读取证书:
1
2
3
4
5
cloudflared tunnel --help
# 如果此命令没报错,说明 cloudflared 已安装。
cloudflared tunnel list
# 如果此命令返回隧道列表(或空列表但无错误),说明 cert.pem 配置成功
Important
这里说的 cert.pem 是一个 TLS 客户端证书,用于客户端的 cloudflared 与 cloudflare 边缘节点之间的身份验证。客户端的 cloudflared 需要用私钥签名,然后 cloudflare 边缘节点用公钥来验证其身份。这个过程与 SSH 连接无关。如果后续使用密钥对进行 SSH 连接的话,整个过程可以用一个比喻来理解:Cloudflare Tunnel 相当于快递公司的运输路线,SSH 密钥对相当于目的地的门锁和钥匙,而 cloudflared 相当于快递员,需要有工作证(Cloudflare 证书,即 cert.pem 文件)才能接单。
3. 写入 SSH 配置文件
接下来可以配置 ~/.ssh/config,让 SSH 自动通过 cloudflared 转发。首先用 vim 编辑器打开配置文件:
1
vim ~/.ssh/config
然后写入配置文件内容:
1
2
3
4
Host ssh.hoigin.cn
HostName ssh.hoigin.cn
User pi
ProxyCommand cloudflared access ssh --hostname %h
🖇️步骤三:连接测试
在 Windows 系统的 PowerShell 中或 Linux 的终端中执行:
1
2
3
ssh pi@ssh.hoigin.cn
# 或者用以下命令
ssh ssh.hoigin.cn
首次连接有可能会弹出浏览器,登录 Cloudflare 后自动建立加密隧道,成功进入树莓派终端。
Caution
Windows系统的上的 cloudflared 不是以系统服务的形式运行的,每次运行 ssh pi@ssh.hoigin.cn 时,cloudflared 会自动启动一个子进程进行 SSH 连接;连接断开后,该进程自动结束。
🔑步骤四:配置密钥对(可选)
1. 生成密钥对
下面的配置过程以 Linux 系统为例。首先,用以下命令生成 SSH 密钥对:
1
2
3
# -t 即 type,指定密钥的类型
# ed25519 是 OpenSSH 官方推荐的一种公钥加密算法,是基于Edwards-curve Digital Signature Algorithm (EdDSA) 的一种具体实现,使用 Curve25519 椭圆曲线
ssh-keygen -t ed25519
接下来会看到类似这样的交互:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/you/.ssh/id_ed25519): [直接回车]
Enter passphrase (empty for no passphrase): [直接回车,除非你需要额外保护]
Enter same passphrase again: [回车]
Your identification has been saved in /home/you/.ssh/id_ed25519
Your public key has been saved in /home/you/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:kIMgstOypcKKdlB9pqGK5GTCeKbAFgkk9MsPksD9dU4 ubuntu@hoigin
The key's randomart image is:
+--[ED25519 256]--+
|Bo. |
|=++... . |
|=+o+.o++ E |
|**= + *o+ |
|B%o= o S. |
|&++ o |
|=+ . . |
|. . |
| |
+----[SHA256]-----+
这里没有设置 passphrase 是因为要实现无交互地使用密钥对进行 SSH 连接。未来如果需要实现自动化脚本的话,也必须要实现「无交互」。另外,还要确保私钥权限为 600:
1
chmod 600 ~/.ssh/id_ed25519
Note
交互过程中出现的 key fingerprint ,即指纹,是对公钥内容进行哈希(hash)后得到的一个短字符串。它的作用是快速、唯一地标识一个 SSH 公钥(比看一长串 base64 字符更方便)。当你第一次 SSH 连接到一个新服务器时,SSH 客户端会显示服务器的公钥指纹,并问你是否信任:
1
2
3
1The authenticity of host 'example.com (1.2.3.4)' can't be established.
2ECDSA key fingerprint is SHA256:AbCdEfGhIjKlMnOpQrStUvWxYz1234567890abc.
3Are you sure you want to continue connecting (yes/no)?
你可以通过其他可信渠道(如控制台、文档)核对这个指纹是否一致,防止连接到假冒的服务器。
Note
交互过程中出现的 randomart image ,即随机艺术图,是一个将密钥指纹可视化为 ASCII 艺术图案的功能,目的是让人更容易肉眼识别和记忆密钥指纹。人对图像的记忆比对字符串更强。如果你经常连接某台服务器,看到它的 RandomArt 图「像一只鸟」,下次如果图变了(比如变成「像一把刀」),你就知道公钥可能被篡改了!
2. 上传公钥至树莓派
使用以下命令进行上传:
1
2
# 替换 your-tunnel-host 为你的实际主机名(如 ssh.hoigin.cn)
ssh-copy-id -i ~/.ssh/id_ed25519.pub pi@your-tunnel-host
系统会提示你输入一次树莓派的密码,之后自动在树莓派创建 ~/.ssh/ 目录并将将公钥追加到 ~/.ssh/authorized_keys,然后设置正确权限(700 / 600)。成功后可以看到输出:
1
2
Number of key(s) added: 1
Now try logging into the machine...
此外,还可以打开树莓派的终端检查公钥是否已经添加至 ~/.ssh/authorized_keys 中。
3. 改写 SSH 配置文件
打开 ~/.ssh/config 文件后,加入指定私钥的配置信息:
1
2
3
4
5
6
Host rpi
HostName ssh.hoigin.cn
User pi
IdentityFile ~/.ssh/id_ed25519 # 指定私钥
IdentitiesOnly yes # 只用这个私钥,避免其他密钥干扰
ProxyCommand cloudflared access ssh --hostname %h
之后再重试「🖇️步骤三:连接测试」即可。
📚说明
- 所有流量均通过 Cloudflare 全球网络加密传输,不暴露树莓派真实 IP。
- 每次连接需通过 Cloudflare Access 身份认证(支持邮箱、2FA 等策略)。
- 该方案适用于任何内网设备,不仅限于 SSH(可扩展至 HTTP、RDP 等协议)。
- 「🔑步骤四:配置密钥对(可选)」中所生成的私钥可以放到 Windows、MacOS、iOS、Android 等其它平台上,实现免密码的 SSH 连接。