借助CloudflareTunnel实现内网穿透

需求描述

  • 海外VPS
  • 域名 最好是拥有主域名
  • CF(cloudflare)账号 订阅了Teams Free Base免费套餐
  • Tabby 开源Shell终端
  • SwitchHosts 开源本地Hosts切换工具
  • CloudflareSpeedTest 开源cloudflare IP优选工具

直接用域名绑定VPS主机IP并访问端口,长期来看,不仅有端口暴露风险,而且还需要忍受线路丢包、延迟波动所带来的命令行输入漂移等问题。

最好能够长期在不对外暴露端口并隐藏VPS主机IP的情况下,能够实现公网或者本地对VPS主机的访问。

VPS主机IP被封禁的情况下,依然能够使用本地Shell终端进行访问。

不依赖特定云厂商环境,能够在多个云厂商之间进行服务发布切换。

操作配置

1. 注册一个CF账号并订阅免费套餐

点击访问cloudflare dashboard进行账号注册。

点击左侧导航栏中的Zero Trust,设置团队名称,不知道怎么填,也可以截取注册邮箱的名称并输入。

付费计划选择第一个0元每月的套餐进行绑定即可。

支付方式选择PayPal,PayPal应该很容易注册,也能够绑定储蓄卡和借记卡。这个0元套餐也绑定几年了,目前还没有变卦。

2. 创建Cloudflare Tunnels

在套餐绑定成功后,在点击进入Zero Trust,然后再点击左侧导航栏中的Networks > Connectors(网络 > 连接器),进入后点击Create a tunnel(创建一个隧道)。创建隧道界面如下:

创建隧道界面

进入页面后,选择点击Select Cloudflared,输入隧道名称,比如vps-tunnel,然后点击Save tunnel进行保存创建。隧道命名界面如下:

隧道命名界面

目前CF tunnel支持多个平台的终端安装,为方便环境切换,现在选择Docker平台,安装命令可以复制出来并进行修改:

隧道连接界面

1
2
3
4
5
6
7
sudo docker run -d \
--name vps-tunnel \
--network bridge \
--restart always \
cloudflare/cloudflared:latest tunnel \
--no-autoupdate run \
--token $yourtoken

$yourtoken替换成刚才在页面中安装命令中的token字符串,docker的network选择的是bridge,使用的默认网段为172.17.0.0,宿主机在此网段的IP为172.17.0.1。当然也可以将network指定为host,此时与宿主机共用端口范围,如果端口被docker占用了,宿主机就不能再占用该端口了。因为采用了host,将端口开在宿主机上,少了一层网络转换,可以提供更好的网络连接和传输性能表现。

3. 在VPS主机上安装cloudflared终端

先按照常规方式SSH登录VPS主机,推荐使用云厂商提供的web shell在线登录,或者也可以通过本地直连VPS主机IP进行登录,后者的话,需要临时忍受网络丢包和延迟波动带来的命令输入漂移等问题。如果IP被封禁,或者只有IPv6地址,但是本地访问不了IPv6地址,那就只能选择前者了。

登录VPS主机后,先要安装docker运行环境,执行如下命令进行安装:

1
2
3
4
5
sudo apt update && sudo apt upgrade -y

curl -fsSL https://get.docker.com -o get-docker.sh

sudo sh get-docker.sh

等待docker安装好后,输入以下命令查看docker是否安装成功:

1
2
sudo docker --version
sudo systemctl status docker

将从cloudflare dashboard上复制并修改后的docker隧道建立命令在VPS主机上执行。如果在cloudflare dashboard显示如下信息,则CF tunnel连接成功。

CF tunnel隧道连接成功

成功后,点击Next进行下一步操作。如果没来得及在VPS主机上连接隧道,也可以点击Next,此页面命令信息是可以重复查看的。

4. 发布应用路由

当隧道连接成功后,接下来就是发布应用,目前可以支持的协议类型有:

  • HTTP
  • HTTPS
  • UNIX
  • TCP
  • SSH
  • RDP
  • UNIX+TLS
  • SMB
  • HTTP_STATUS
  • BASTION

在发布应用页面中,如果Domain主域名无法选择,可以去CF上买了一个域名。如果有其他厂商提供的域名,也可以让CF进行托管。
如果主域名没有绑定其他服务,则Subdomain可以为空,但推荐还是自定义一个子域名,比如输入vps-tunnel

目前准备发布SSH协议的应用,Path可以不用填写,保持默认即可。Service信息栏进行如下配置:

  • Type:SSH
  • URL :172.17.0.1:22

应用发布设置界面

本次发布的应用是为了SSH登录,协议类型选择SSH,目前docker部署的cloudfalred终端是使用了bridge网络,而宿主机在该网络的IP是172.17.0.1,同时宿主机的SSH端口默认是22,如果不是默认的,特别是后续修改了SSH端口,URL中的端口需要改成对应的端口。

如果cloudfalred终端是采用了host网络,Service信息栏进行如下配置:

  • Type:SSH
  • URL :localhost:22

点击Complete setup进行发布。发布成功后的效果如下:

应用发布成功界面
域名代理成功界面

5. 使ProxyCommand登录VPS主机

打开Tabby Shell终端,点击配置中Profiles & connections,选择New profileSSH connection来创建一个SSH登录配置。配置如下:

  • Name:vps-tunnel
  • Connection:Proxy command
  • Proxy command$CloudflaredPath access ssh --hostname $Domain
  • Usename:VPS主机可登录的用户名

Authentication method可按需选择,如果是密码口令登录,选择Password,如果是SSH密钥登录,则选择Key

$CloudflaredPath是cloudfalred终端程序的路径,示例路径为D:\\cloudflared.exe如果没有,可点击Windows版进行下载,下载好后,建议将文件重命名为cloudflared.exe

$Domain就是之前的子域名和主域名的组合Subdomain.Domain,也可在vps-tunnel隧道中的Published application routes页面中查询。

保存好后,就可以选择该SSH配置进行登录了。需要注意的是,登录的时候会打开一个cloudflared.exe应用程序窗口,如果手动关闭,会导致SSH会话结束,如果是同一域名开启多个SSH会话,则该窗口只有一个。除此之外,同一路径下cloudflared.exe只能供一个域名使用,如果有多个域名,建议将cloudfalred终端程序分发到多个目录,或者在同一目录下,复制多个命名不同的cloudfalred终端程序。

6. 将VPS主机服务端口映射到本地

在CF tunnel中嵌套SSH tunnel将VPS主机端口映射到本地,可将VPS服务只暴露给本地,这可用于服务器环境运行测试,等测试好后,再通过云厂商提供的平台防火墙将端口对外开放出去。

以docker部署nginx为例,将nginx容器80端口映射到宿主机的8080端口,现在通过CF tunnel和SSH tunnel将宿主机的8080端口映射到本地的8080端口上,在本地浏览器上访问http://localhost:8080,即可访问nginx上的网页。在本地使用powershell执行如下命令:

1
2
3
4
ssh -f -N \
-i "$PrivateKeyPath" \
-o "ProxyCommand=$CloudflaredPath access ssh --hostname $Domain" \
-L 8080:127.0.0.1:8080 $Username@$Domain
  • -f:让 SSH 客户端在后台运行
  • -N:只建立连接,不执行远程命令
  • -i:指定SSH私钥文件路径

$PrivateKeyPath是SSH的私钥文件路径,示例路径为$HOME\.ssh\id_rsa,使用$HOME是为了避免中文路径乱码。

$CloudflaredPath是cloudfalred终端程序的路径,示例路径为D:\\cloudflared.exe

$DomainPublished application routes页面中的应用发布域名

Username是VPS宿主机上可登录的用户名

输入命令运行后,在浏览器上访问http://localhost:8080即可访问VPS上的nginx网页。

需要注意的是,powershell执行命令后不要关闭,如果手动关闭,则无法成功建立SSH隧道映射。

故障排查

1. Docker中的cloudflared无法和宿主机通信

这个一般是防火墙拦截了来自docker网络中的请求,只要允许访问即可。

  • 通用方式
1
2
# 允许来自 docker0 网卡的所有流量进入
sudo iptables -I INPUT -i docker0 -j ACCEPT
  • Ubuntu/Debian
1
2
3
4
# 允许来自 docker0 网卡的所有流量进入
sudo ufw allow in on docker0
# 重新加载配置生效
sudo ufw reload
  • RHEL/CentOS/Fedora/Rocky
1
2
3
4
# 将 docker0 接口添加到信任区域(允许该网卡的所有入站流量)
sudo firewall-cmd --permanent --zone=trusted --add-interface=docker0
# 重新加载配置生效
sudo firewall-cmd --reload
  • Arch Linux/OpenSUSE

编辑/etc/nftables.conf,在input链中添加:

1
sudo vim /etc/nftables.conf
1
2
3
4
5
table inet filter {
chain input {
iifname "docker0" accept
}
}

然后运行如下代码进行加载:

1
sudo nft -f /etc/nftables.conf

2. Cloudflare给域名分配的IP延迟太高

cloudflare对于内地常常分配欧美IP进行响应,导致高延迟易丢包,解决办法就是在本地Hosts中把域名指向cloudflare优选后的IP,一般是日本节点的IP,延迟大概在80ms-90ms之间,虽然延迟依然不低,但是胜在稳定。如果是部署在美西的VPS,传输路径如下:

  • 美西VPS数据中心 -> 美西CF数据中心 -> 日本CF数据中心 -> 本地
  • 本地 -> 日本CF数据中心 -> 美西CF数据中心 -> 美西VPS数据中心

使用CloudflareSpeedTest进行IP优选,优选开始前,最好将网络代理或者加速器关闭,避免影响IP优选质量。以下是优选好的IP:

  • 162.159.38.82
  • 172.64.229.181
  • 162.159.44.167
  • 162.159.39.25

以管理员的身份打开SwitchHosts,添加一个新的Hosts配置,命名为vps-tunnel,添加如下记录:

1
$IP $Domain

$IP为通过优选工具得到的CF边缘节点IP
$DomainPublished application routes页面中的应用发布域名

编辑好后,点击配置名称旁边的开关,如果是绿色就代表操作成功。SwitchHosts只是在原有系统Hosts基础上添加记录,如果有相同记录,以新加入的为主,即使SwitchHosts退出或者系统重启依然生效。需要注意的是,如果命令行ping域名没有变化,建议重启命令行后再进行操作。

3. Powershell因私钥权限而无法建立SSH隧道

1
2
3
4
ssh -f -N \
-i "$PrivateKeyPath" \
-o "ProxyCommand=$CloudflaredPath access ssh --hostname $Domain" \
-L 8080:127.0.0.1:8080 $Username@$Domain

执行上述命令后如果出现下述提示:

It is required that your private key files are NOT accessible by others.

则表示你的SSH私钥文件的权限不满足powershell的安全设置,可通过修改密钥文件权限或者更换密钥路径来解决。

  • 修改密钥文件权限
1
2
3
4
5
6
7
8
# 重置并禁用权限继承
icacls "$PrivateKeyPath" /inheritance:r

# 只给当前登录用户授权
icacls "$PrivateKeyPath" /grant:r "${env:USERNAME}:F"

# 检查权限
icacls "$PrivateKeyPath"

需要注意$PrivateKeyPath的格式,示例为D:\id_rsa

  • 更换密钥文件路径

将私钥文件放到C盘的用户 > $用户名中的.ssh目录中,$用户名是你操作系统登录时的用户名。如果没有.ssh目录就新建一个.ssh文件夹,并将私钥文件放入该目录。如果.ssh目录中有重名的私钥文件,可将本次私钥文件重命名后放入其中。

参考信息

1. Tabby github开源项目

https://github.com/Eugeny/tabby

2. SwitchHosts github开源项目

https://github.com/oldj/SwitchHosts

3. CloudflareSpeedTest github开源项目

https://github.com/XIU2/CloudflareSpeedTest


借助CloudflareTunnel实现内网穿透
https://blog.commentsdebugger.com/2026/03/30/借助CloudflareTunnel实现内网穿透/
作者
Debugger
发布于
2026年3月30日
许可协议