如何利用cloudflare的zerotrust隧道做内网穿透?

利用Cloudflare的Zero Trust隧道实现内网穿透,主要步骤如下:

  1. 准备工作
    • 注册一个Cloudflare账号。
    • 购买并将你的域名添加到Cloudflare的DNS服务中。
    • 开通Cloudflare Zero Trust服务(免费版即可)。
  2. 安装cloudflared客户端
    • 在本地设备(如家用服务器、NAS或路由器)上安装cloudflared客户端。
    • 例如macOS可用brew install cloudflared,Windows可下载安装包并安装。
  3. 登录并创建隧道
    • 通过命令cloudflared tunnel login登录Cloudflare账户,生成认证文件。
    • 使用cloudflared tunnel create <tunnel-name>创建一个隧道,系统会生成Tunnel UUID和凭证文件^1_1
  4. 配置DNS解析 - 将隧道绑定到你的域名子域名上,例如: cloudflared tunnel route dns <tunnel-name> subdomain.yourdomain.com - 这样外部访问该域名时会通过Cloudflare隧道转发 到你的内网服务。
  5. 编写配置文件
    • ~/.cloudflared/config.yml中配置隧道参数,例如指定隧道ID、凭证文件路径和内网服务地址 (如http://localhost:端口)。
    • 配置示例:
tunnel: <Tunnel-UUID>
credentials-file: /root/.cloudflared/<Tunnel-UUID>.json
ingress:
  - hostname: subdomain.yourdomain.com
    service: http://localhost:5173
  - service: http_status:404
- 验证配置文件:`cloudflared tunnel ingress validate`。
  1. 运行隧道 - 启动隧道服务: cloudflared tunnel --config ~/.cloudflared/config.yml run <Tunnel-UUID> - 可根据网络 环境调整协议参数,如--protocol http2避免UDP被阻断。
  2. 访问内网服务
    • 通过绑定的域名(如subdomain.yourdomain.com)即可从外网访问内网服务,实现内网穿透。

补充说明:

  • Cloudflare Tunnel支持HTTP/HTTPS协议的服务穿透,其他协议(如SSH、SMB)需要额外客户端配置。
  • 该方案无需公网IP,且免费不限流量,但国内访问速度可能受限于网络环境。
  • 也可以结合Cloudflare WARP客户端实现私有网络访问。

综上,利用Cloudflare Zero Trust的Tunnel功能,通过注册账号、创建隧道、配置DNS和运行客户端,即可轻松实现内网穿透,安全稳定 地将内网服务暴露到公网访问。


在本地设备(如家用服务器、NAS或路由器)上安装cloudflared客户端。 家里有pve虚拟机搭建的ubuntu服务器

你家里用的是基于Proxmox VE(PVE)虚拟机管理的Ubuntu服务器,想安装Cloudflare的cloudflared客户端实现内网穿透,可以参考以下 步骤:

  1. 下载cloudflared的Deb安装包 在Ubuntu服务器上执行命令下载最新的cloudflared deb包:
curl -L --output cloudflared-linux-amd64.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
  1. 安装cloudflared 使用dpkg安装:
sudo dpkg -i cloudflared-linux-amd64.deb

安装完成后,可以用cloudflared --version验证安装是否成功。3. 登录Cloudflare账号并授权 执行:

cloudflared tunnel login

该命令会输出一个URL,复制到浏览器打开,登录Cloudflare账号并授权,完成后会在~/.cloudflared/cert.pem生成认证文件。4. 创建隧道 创建一个隧道并记录返回的UUID和凭证文件路径:

cloudflared tunnel create <tunnel-name>
  1. 配置隧道/etc/cloudflared/config.yaml(或~/.cloudflared/config.yml)中写入配置,例如:
tunnel: <Tunnel-UUID>
credentials-file: /root/.cloudflared/<Tunnel-UUID>.json
protocol: http2
ingress:
  - hostname: yoursubdomain.yourdomain.com
    service: https://localhost:你的内网服务端口
    originRequest:
      noTLSVerify: true
  - service: http_status:404

这里hostname是你要绑定的域名子域名,service是你内网服务的地址(比如PVE默认管理界面是https://localhost:8006)。6. 将隧道绑定到域名 执行:

cloudflared tunnel route dns <tunnel-name> yoursubdomain.yourdomain.com

这会自动在Cloudflare DNS中添加对应的解析记录。7. 注册为系统服务(可选) 方便开机自启:

cloudflared service install
systemctl enable cloudflared
systemctl start cloudflared
  1. 访问内网服务 通过浏览器访问https://yoursubdomain.yourdomain.com即可远程访问PVE或其他内网服务。

这个方案不需要公网IP,且安全稳定,适合你用PVE虚拟机运行的Ubuntu服务器环境。

如果你需要穿透其他协议(如SSH),也可以在配置文件中添加对应的ingress规则,Cloudflare Tunnel支持多种协议转发。


这句要什么时候开启?

“cloudflared service install”这条命令的作用是将cloudflared隧道安装为系统服务,实现开机自启动。你应该在完成隧道创建和 配置文件编写之后执行这条命令,也就是当你确认隧道配置正确并且能正常通过命令行启动后,就可以运行:

cloudflared service install
systemctl start cloudflared
systemctl enable cloudflared

这样做的时机通常是在:

  • 你已经通过cloudflared tunnel create创建了隧道
  • 配置文件(config.yml)已正确设置并放置好
  • 在命令行用cloudflared tunnel run <tunnel-name>测试隧道能正常运行

确认无误后,执行cloudflared service install将其注册为系统服务,启动服务并设置开机自启,保证服务器重启后隧道自动运行, 无需手动启动。

简单来说,“cloudflared service install”是在你完成隧道配置并确认能正常运行后,为了让隧道后台持续运行且开机自动启动时执 行的命令


originRequest:

  noTLSVerify: true</q> 这句要什么时候开启?
`originRequest: noTLSVerify: true` 这句配置的作用是**关闭对内网服务TLS证书的验证**,通常在以下情况下开启:
  • 你的内网服务使用了自签名证书或者证书不被Cloudflare信任的CA签发,导致Cloudflare隧道访问时出现TLS验证错误。
  • 你需要通过HTTPS访问内网服务,但不想或无法配置有效的受信任证书。

开启后,Cloudflare Tunnel在访问内网服务时不会校验证书的有效性和域名匹配,避免因证书问题导致连接失败。

总结:

  • 如果你的内网服务是HTTP(非加密),无需开启。
  • 如果是HTTPS且证书是自签名或无效证书,建议开启noTLSVerify: true
  • 如果内网服务证书是由受信任CA签发,且证书有效,建议保持默认false以保证安全。

你可以在Cloudflare Tunnel配置文件中对应的ingress规则下添加此配置,例如:

ingress:
  - hostname: subdomain.yourdomain.com
    service: https://localhost:443
    originRequest:
      noTLSVerify: true

开启后,重启cloudflared隧道使配置生效即可。

参考示例和说明均来自Cloudflare Tunnel的官方及社区实践文档。


是否需要在内网主路由做端口映射?

利用Cloudflare Zero Trust的Tunnel做内网穿透时,通常不需要在内网主路由上做端口映射(端口转发)

原因是Cloudflare Tunnel是由内网服务器主动发起到Cloudflare网络的安全隧道连接,Cloudflare的公网节点通过这个隧道反向代理访 问内网服务,因此不需要暴露内网主机的端口到公网,也不需要路由器做NAT端口映射。

具体说明:

  • 内网设备主动连接Cloudflare,建立隧道,Cloudflare负责接收外部请求并转发到内网。
  • 只要内网服务器能访问Cloudflare节点(一般只需有互联网连接),即可实现内网穿透。
  • 端口映射通常是传统内网穿透方式(如FRP、花生壳)所需,Cloudflare Tunnel省去了这一步。
  • 但如果你要穿透的服务在内网其他机器上,且这些机器无法直接访问Cloudflare,那么你可能需要在内网路由器做端口映射,将请求 转发到运行cloudflared的机器上。
  • 另外,如果你用Cloudflare Tunnel映射非HTTP协议(如SSH、RDP),也无需端口映射,只需配置隧道对应协议转发即可。

总结: **只要运行cloudflared隧道的机器能上网,且配置了正确的Cloudflare隧道和DNS解析,通常无需在路由器上做端口映射。**这 也是Cloudflare Tunnel相比传统内网穿透方案的最大优势之一。


错误例子一:cloudflared tunnel route dns home01 syntalk.737703.xyz

Failed to add route: code: 1003, reason: Failed to create record syntalk.737703.xyz with err An A, AAAA, or CNAME record with that host already exists. For more details, refer to https://developers.cloudflare.com/dns/manage-dns-records/troubleshooting/records-with-same-name/.

你遇到的错误:

Failed to add route: code: 1003, reason: Failed to create record syntalk.737703.xyz with err An A, AAAA, or CNAME record with that host already exists.

这是因为你尝试通过命令 cloudflared tunnel route dns home01 syntalk.737703.xyz 创建的DNS记录(A、AAAA或CNAME)在 Cloudflare的DNS管理中已经存在了相同名称的记录,Cloudflare不允许重复创建同名的DNS记录^6_1

解决方案:

  1. 检查并删除冲突的DNS记录
    • 登录Cloudflare控制面板,进入对应域名的DNS管理页面。
    • 查找是否已经存在名为 syntalk 的A、AAAA或CNAME记录。
    • 如果存在且不再需要,删除该记录。
    • 然后重新执行 cloudflared tunnel route dns 命令。
  2. 使用覆盖参数强制覆盖已有记录
    • 如果你确认要用隧道的记录替换已有记录,可以使用命令的强制覆盖参数:
cloudflared tunnel route dns home01 syntalk.737703.xyz --overwrite-dns
- 该参数会覆盖已有的DNS记录,避免冲突错误。
  1. 使用不同的子域名
    • 如果不想删除已有记录,可以换用一个未被占用的子域名,比如 tunnel.syntalk.737703.xyz,避免同名冲突。
  2. 手动在Cloudflare面板创建CNAME记录(可选)
    • 你也可以手动在Cloudflare DNS面板添加一个CNAME记录,指向 uuid.cfargotunnel.com(具体隧道地址),然后跳过自动创建 DNS记录这步。

参考说明

  • Cloudflare不允许同一个域名下存在多个相同名称的A、AAAA或CNAME记录^6_2
  • 该错误是Cloudflare Tunnel常见的DNS冲突问题,官方建议检查并删除已有冲突记录,或使用--overwrite-dns参数覆 盖^6_3^6_4
  • 如果你在多台机器上创建多个隧道并绑定同一子域名,也会出现此错误,需合理规划子域名或使用单隧道多路由方案^6_3

总结: 你需要先登录Cloudflare DNS管理,删除或修改已有的 syntalk.737703.xyz 相关


错误例子二:cloudflared service install

2025-07-05T12:31:21Z INF Using Systemd 2025-07-05T12:31:21Z ERR error generating service template error="cloudflared service is already installed at /etc/systemd/system/cloudflared.service; if you are running a cloudflared tunnel, you can point it to multiple origins, avoiding the need to run more than one cloudflared service in the same machine; otherwise if you are really sure, you can do cloudflared service uninstall to clean up the existing service and then try again this command" cloudflared service is already installed at /etc/systemd/system/cloudflared.service; if you are running a cloudflared tunnel, you can point it to multiple origins, avoiding the need to run more than one cloudflared service in the same machine; otherwise if you are really sure, you can do cloudflared service uninstall to clean up the existing service and then try again this command

你执行 cloudflared service install 时出现的错误:

cloudflared service is already installed at /etc/systemd/system/cloudflared.service; if you are running a cloudflared tunnel, you can point it to multiple origins, avoiding the need to run more than one cloudflared service in the same machine; otherwise if you are really sure, you can do `cloudflared service uninstall` to clean up the existing service and then try again this command

这是因为系统中已经安装并启用了一个 cloudflared 的 systemd 服务,同一台机器上默认只能有一个 cloudflared 服务实例

解决方案和建议

  1. 不必重复安装服务,配置一个服务支持多个隧道或多个域名(多个origin)即可
    • Cloudflare官方推荐在同一台机器上运行一个 cloudflared 服务实例,通过配置文件的 ingress 配置来支持多个域名和多个 内网服务。
    • 你可以在同一个 config.yml 中添加多条 ingress 规则,分别指向不同的主机名和服务端口。
    • 这样无需多次安装服务,也避免资源浪费。
  2. 如果确实需要多个独立的cloudflared服务实例
    • 需要手动创建多个 systemd 服务单元文件(比如 cloudflared1.servicecloudflared2.service),每个服务使用不同的配 置文件和凭证。
    • 这是因为 cloudflared service install 命令只会安装一个默认服务文件。
    • 详细做法是复制并修改 /etc/systemd/system/cloudflared.service 文件,调整 ExecStart 指令指向不同的配置文件和凭 证,然后启用多个服务。
  3. 如果之前安装的服务不再需要,可以先卸载再重装
sudo cloudflared service uninstall
sudo cloudflared service install
sudo systemctl start cloudflared
sudo systemctl enable cloudflared

这样清理旧服务后重新安装。

参考配置示例(单服务支持多域名)

tunnel: <Tunnel-UUID>
credentials-file: /root/.cloudflared/<Tunnel-UUID>.json

ingress:
  - hostname: domain1.example.com
    service: http://localhost:8080
  - hostname: domain2.example.com
    service: http://localhost:9090
  - service: http_status:404

总结

  • 默认情况下,一台机器只需安装一个cloudflared systemd服务,通过配置文件支持多个域名和服务。
  • 如果要运行多个隧道实例,需手动创建多个服务单元。
  • 遇到该错误时,确认是否已有服务在运行,避免重复安装。
  • 需要时可先卸载旧服务再重新安装。

这样既符合Cloudflare官方推荐的最佳实践,也能避免服务冲突和管理复杂度。