使用Cloudflare Tunnel转发任意端口

date
Dec 10, 2023
slug
use-cloudflared-tunnel-proxy-any-port
status
Published
tags
Tech
Devops
Cloudflare
summary
实现在只有IPV4单栈网络环境访问家里IPV6单栈服务器,无需自备中转服务器
type
Post

背景

我的家里使用的是移动宽带,由于众所周知(IP不够)的原因移动只给IPV6,并且没有申请IPV4的可能性,但是我在家里的Exsi server上部署了很多的服务,例如NAS,相册,电影点播服务,以及开发用的一些环境(ssh/mysql/mq)
首先如果访问者也有IPV6那就不用说了,DDNS解析一个域名直接连接就可以了。

问题

那如果我们的访问者只有IPV4呢?我们如何实现在只有IPV4的网络环境访问家里的服务器呢?
网上一搜就有一大把的ugly方案,例如ngrok,frp,zerotier,这些方案我都曾经尝试过,在我看来一点都不完美。
我的方案是基于Cloudflare 提供的Zerotrust 方案,Cloudflare Tunnel 通过在本地网络运行的一个 Cloudflare 守护程序,与 Cloudflare 云端通信,将云端请求数据转发到本地网络的 IP + 端口。

前置条件

  • 拥有一个域名
  • 将域名 DNS 解析托管到 CF
  • 内网有一台服务器(也可以是PC or 路由器),用于运行本地与 cloudflare 通信的 cloudflared 程序
  • 一张境内双币信用卡(仅需要添加付款方式,服务是免费的,free tier足够大部分人使用)

Web服务

如果我们是需要暴露一个HTTP服务出来,那么很简单,这种教程网上太多了。
  1. 打开 Cloudflare Zero Trust 工作台面板
  1. 创建 Cloudflare Zero Trust ,选择免费计划。需要提供付款方式,使用境内的双币卡即可
  1. 完成后,在 Access Tunnels 中,创建一个 Tunnel。
  1. 选择 Cloudflared 部署方式。
    1. Tunnel 需要通过 Cloudflared 来建立云端与本地网络的通道,这里推荐选择 Docker 部署Cloudflared 守护进程以使用 Tunnel 功能。
  1. 配置域名和转发URL
    1. 为你的域名配置一个子域名(Subdomain),Path 留空,URL 处填写内网服务的IP加端口号。注意 Type 处建议使用 HTTP,因为 Cloudflare 会自动为你提供 HTTPS,因此此处的转发目标可以是 HTTP 服务端口
接着访问刚刚配置的三级域名,例如 https://app.example.com(你没看错,cloudflare 已经自动为域名提供了 https 证书)就可以访问到内网的非公端口号服务了。
一个 Tunnel 中可以添加多条三级域名来跳转到不同的内网服务,在 Tunnel 页面的 Public Hostname 中新增即可。
更细节的操作步骤,以及如果不想将服务暴露给所有人,Cloudflare还贴心的帮你提供了一套安全完善的认证机制,你可以参考少数派提供的教程,这不是我这篇文章想要讲的重点内容。
 

任意TCP服务

网上轻易能找到的教程就是前半部分了,这种内容只能暴露HTTP服务以及特定的SSH和VNC服务,而我想讲的重点是,如果我们想要连接到我的开发环境的非HTTP服务呢?任意一个TCP端口,可能是一个RDP协议的端口,也可能是MySQL的服务,前面那部分教程是无法帮你转发非HTTP服务的,网上的教程大家抄来抄去,很少有人讲这部分。
话不多说,直接开始,这里我们以内网的MySQL和SSH服务举个栗子。

SSH

  • 还是需要按照Web服务的第五步在 Tunnel 页面的 Public Hostname 中新增一条记录,协议按需选择,我这里选的SSH,也可以选TCP
notion image
  • 现在是在访问的电脑上操作,执行登录命令,这个时候浏览器会自动打开一个网址用于oauth授权。
  • 在客户端修改 ~/.ssh/config 文件, 通过ProxyCommand 来调用 cloudflared 创建一个隧道,在这之前你可能需要先登录一下
  • 最后ssh home 即可。
 

RDP(以及任意TCP端口)

跟上面的SSH相同的步骤,在 Tunnel 页面的 Public Hostname 中新增一个域名,只是不再需要修改ssh config,直接通过命令启动端口代理
 
实际上只要我们成功地转发了SSH,即可通过SSH建立隧道来转发更多的端口,不再需要这样单独配置,如果没有SSH服务当我没说,按照这个方法配置也行。
 

新更新 NAT打洞

这部分更新在这篇文章写完之后一年,一个偶然的机会我测试之后发现我家的移动宽带NAT居然是NAT1 FullClone

参考链接:


© Devpan 2023 - 2024