我在家里的内网中的若干台服务器上运行了一些服务,包括一些web服务,分别监听在不同端口上(如 80xx 的 HTTP 服务、84xx 的 HTTPS 服务)。对于其中的一个web服务,我希望通过一个域名子域名,用标准的 443 端口从公网访问这些服务,而且不需要在路由器上做端口映射或暴露家庭公网 IP。
以下的配置,我使用我的一台 Mac mini 作为跳板机器。将它自身的服务以及内网的其他服务暴露出去。
Cloudflare Tunnel 是最佳方案,原因如下:
cloudflared 建立出站连接到 Cloudflare,不需要在路由器上开放任何入站端口在 Cloudflare Registrar 注册域名后,域名会自动使用 Cloudflare 的 DNS。这一步不是必须的。只要你拥有自己的域名,就可以通过以下两种方式实现同样的效果:
mac-mini)如下
brew install cloudflared
确认安装成功:
cloudflared --version
运行控制台提供的安装命令(包含你的 Tunnel token):
sudo cloudflared service install eyJhIjoi...<你的TOKEN>
⚠️ 安全提醒:Tunnel token 是你的连接凭证,任何持有它的人都可以连接你的 Tunnel。不要在公开场合分享。
安装后,如果控制台一直显示 "Waiting for your Tunnel to connect...",按以下步骤排查:
sudo launchctl start com.cloudflare.cloudflared
cat /Library/Logs/com.cloudflare.cloudflared.err.log
如果日志中出现以下错误:
ERR Failed to dial a quic connection error="failed to dial to edge with quic: timeout: no recent network activity"
ERR Unable to establish connection with Cloudflare edge error="TLS handshake with edge error: EOF"
并且连接的 IP 是 198.18.x.x(WARP 本地代理 IP 段),说明 Cloudflare WARP 客户端正在拦截 cloudflared 的流量。
原因:WARP 开启后会接管设备的所有出站流量,包括 cloudflared 需要的 UDP 7844 端口(QUIC 协议)连接,导致协议冲突。
解决方法:关闭 WARP
在 Mac mini 上点击菜单栏的 WARP 图标,将开关切换到关闭,然后重启 tunnel 服务:
sudo launchctl stop com.cloudflare.cloudflared
sudo launchctl start com.cloudflare.cloudflared
检查日志确认连接成功:
tail -20 /Library/Logs/com.cloudflare.cloudflared.err.log
看到 Registered tunnel connection 即表示连接成功。
关于 WARP:WARP 是 Cloudflare 的客户端 VPN,用于加密设备流量和隐藏 IP。对于作为服务器使用的 Mac mini,关闭 WARP 基本没有负面影响 — Tunnel 本身已经提供了加密和安全防护。WARP 更适合客户端设备(手机、笔记本)使用。
Tunnel 连接成功后,配置路由规则将子域名映射到本地服务:
| 字段 | 值 |
|---|---|
| Subdomain | a(你想用的子域名) |
| Domain | 选择你的域名(如 foobar.page) |
| Type | HTTP(本地服务是 HTTP)或 HTTPS(本地服务有 SSL) |
| URL | localhost:8080(本地服务地址和端口) |
Cloudflare 会自动创建 CNAME DNS 记录,将子域名指向 Tunnel。
Type 指的是 cloudflared 连接本地服务时使用的协议,不是外部访问的协议。外部访问始终是 https://(443 端口加密),这是 Cloudflare 自动处理的。
| 本地服务情况 | Type | URL | 说明 |
|---|---|---|---|
| 8080 端口,无 SSL | HTTP | localhost:8080 |
cloudflared 用 HTTP 连接本地服务 |
| 8443 端口,有 SSL | HTTPS | localhost:8443 |
cloudflared 用 HTTPS 连接本地服务 |
无论选 HTTP 还是 HTTPS,外部用户访问的都是 https://a.你的域名.com(443 端口,加密的)。
推荐使用 localhost:端口 而不是 公网域名:端口:
| 方式 | 优点 | 缺点 |
|---|---|---|
localhost:8080 ✅ |
本地回环,最快最稳定,不依赖外部 DNS | 无 |
my.original-domain-name.com:8443 |
可以复用已有域名 | 可能遇到 hairpin NAT 问题,增加延迟,多一个故障点 |
同一个 Tunnel 可以添加多个 Public Hostname,分别指向不同的本地服务端口:
| Subdomain | Domain | Type | URL |
|---|---|---|---|
a |
foobar.page |
HTTP |
localhost:8089 |
b |
foobar.page |
HTTPS |
localhost:8443 |
访问 https://a.foobar.page(443 端口)→ Cloudflare 网络 → Tunnel → http://localhost:8080(Mac mini 本地服务)
全程加密、无需公网 IP、无需端口映射、开机自启动。