使用 Cloudflare 实现内网穿透:配置过程和问题解决
date
Aug 22, 2024
slug
using-cloudflare-for-network-penetration-configuration-and-troubleshooting
status
Published
tags
工具
网络
summary
配置 Cloudflare Zero Trust Tunnel,解决 Docker 默认网络隔离导致容器无法访问宿主机服务的问题。
type
Post
配置过程
- 首先,登录到 Cloudflare 账号并进入 Dashboard。在左侧菜单栏中点击 “Zero Trust”,进入 Zero Trust 页面后,再点击 “Network - Tunnels”,进入 Tunnels 配置页面。
- 点击 “Create a Tunnel”,选择 “Cloudflared” 并点击 “Next”。为 Tunnel 命名后,继续点击 “Next”。
- 为了简化部署,这里使用 Docker。将页面中的命令复制到终端并执行。
如果配置成功,当前页面将显示已经成功连接的设备信息。
- 点击 “Next”,进入下一步配置。在此步骤中,您需要配置访问的域名(要确保您的域名托管在 Cloudflare)。
- 然后,配置要通过内网穿透访问的服务地址。比如,如果您本机通过 Docker 运行了一个 WebUI 服务,端口为 1234,那么这里就填写
http://localhost:1234
。保存配置后,尝试通过刚才设置的域名访问服务。
解决无法通过公网域名访问的问题
在配置过程中,我遇到了这个问题:无法通过刚刚配置的公网域名访问到服务。
原因排查
宿主机上执行
curl http://localhost:1234
可以正常访问服务,但 Cloudflared 容器日志中显示它尝试连接 http://localhost:1234
时访问被拒绝。以下是 AI 给出的分析:背景:Docker 网络模式
Docker 默认有多种网络模式,其中常用的包括:
- Bridge 模式(默认):容器通过一个虚拟网桥与宿主机通信。每个容器都有自己的独立网络命名空间,
localhost
只指向容器内部的地址,而不指向宿主机。
- Host 模式:容器与宿主机共享网络命名空间,容器直接使用宿主机的网络接口,
localhost
在这种模式下指向宿主机的localhost
。
问题原因:网络隔离
当
cloudflared
容器运行在默认的 bridge
模式下时,容器与宿主机的网络是隔离的:- 在
bridge
模式下,localhost
对容器来说是它自己的网络命名空间。尝试访问localhost:15432
实际上是在访问容器内部的localhost
,而不是宿主机的地址。
- 如果你想在
bridge
网络模式下从容器访问宿主机的服务,不能直接使用localhost
,而是需要通过宿主机在 Docker 网桥中的 IP 地址(通常是172.17.0.1
)来访问。
解决方法:使用 Host 网络模式
当你使用
--network host
启动 cloudflared
时,容器与宿主机共享网络命名空间,意味着:- 容器内的
localhost
就等同于宿主机的localhost
。
- 这样一来,
cloudflared
能够直接访问宿主机上运行的 WebUI 服务,因为它们共享相同的网络环境。
因此,在配置过程中第 3 步的命令中,需要进行如下调整:
- 添加
-d
参数使容器在后台运行。
- 添加
-network host
参数使容器与宿主机共享网络命名空间。