没有公网 IP,如何让家里的服务器通过域名访问?——Cloudflare Tunnel 实战指南

本文以"家庭宽带没有公网 IPv4"为前提,使用 Cloudflare Tunnel 将家里的 Web/API 服务安全地发布到公网。

**隐私说明:**本文示例全部使用虚构域名、占位 IP、占位令牌和通用项目名,未包含真实域名、真实公网地址、Cloudflare 账号信息、Tunnel Token 或任何个人敏感信息。

一、为什么家里的服务器没有公网 IP 也能访问?

传统的公网访问通常是:

text 复制代码
用户浏览器
 ↓
公网 IP:443
 ↓
家庭路由器端口转发
 ↓
家里的服务器
 ↓
Nginx / Spring Boot / Docker

但很多家庭宽带没有可直接入站访问的公网 IPv4,可能处于运营商 CGNAT 后面。这种情况下,即使你知道家里的出口地址,也通常无法直接从公网访问家里的服务器。

Cloudflare Tunnel 换了一种思路:不要求公网主动"打进"家里,而是让家里的 cloudflared 主动向 Cloudflare 建立出站连接。 Cloudflare 官方文档将其描述为 outbound-only 连接,因此不需要给家庭服务器提供公网 IP,也不需要开放家庭路由器的入站端口。

最终链路可以变成:

text 复制代码
用户
 ↓
https://api.example.com
 ↓
Cloudflare
 ↓
Cloudflare Tunnel
 ↓
家里服务器 cloudflared
 ↓
Nginx / Docker / Spring Boot

Cloudflare Tunnel 支持公开发布 HTTP/HTTPS 应用,也支持其他协议;对于公开 Web/API 场景,最适合使用"Published application"路由。


二、准备条件

开始之前准备好下面几个东西:

  1. 一个 Cloudflare 账号。
  2. 一个已经托管到 Cloudflare 的域名。
  3. 家里的服务器可以正常访问互联网。
  4. 家里的 Web/API 服务已经在本机监听,例如 127.0.0.1:8080 或某个 Docker 网络中的服务。

Cloudflare 官方当前的 Tunnel 入门文档要求:Cloudflare 账号、一个托管在 Cloudflare 上的域名,以及一台可以访问互联网并运行 cloudflared 的服务器。

如果家庭网络对出站连接有限制,还需要确保服务器能够访问 Cloudflare Tunnel 所需的网络端口;官方文档特别提到可以检查 7844 端口的连通性。


三、为什么推荐"远程管理型 Tunnel"

Cloudflare Tunnel 有本地管理和远程管理两种方式。

现在的家庭服务器 / Docker 部署场景,我更推荐远程管理型 Tunnel(remotely-managed tunnel)

  • Tunnel 配置存放在 Cloudflare。
  • 可以直接在 Cloudflare Dashboard 中管理 Hostname 和 Service。
  • Docker 部署非常方便。
  • 以后换机器、迁移服务时,不必重新维护一堆本地配置文件。

Cloudflare 当前文档也明确建议大多数场景使用 remotely-managed tunnel,并且针对 Docker 推荐这种方式。


四、第一步:把域名交给 Cloudflare 管理

进入 Cloudflare Dashboard,把你的域名添加进去,并按照 Cloudflare 给出的要求修改域名注册商处的 Nameserver。

注意:

"域名注册商"和"DNS 服务商"不是一回事。

域名可以继续在原注册商购买,但 DNS 权威解析可以交给 Cloudflare。

完成后,在 Cloudflare 的域名页面确认 DNS 已经生效。


五、第二步:创建 Cloudflare Tunnel

进入 Cloudflare Dashboard:

text 复制代码
Networking
 → Tunnels
 → Create Tunnel

输入一个 Tunnel 名称,例如:

text 复制代码
home-server

名字只是为了方便管理,不需要和域名一致。

Cloudflare 当前 Dashboard 创建 Tunnel 的流程就是在 Networking → Tunnels 中创建新的 Tunnel,然后选择服务器操作系统并获取安装命令。


六、第三步:在家里的服务器运行 cloudflared

假设家里的服务器是 Linux,并且已经安装 Docker。

Cloudflare Dashboard 创建 Tunnel 后,会给出对应的安装命令。对于 Docker,官方当前推荐的运行方式类似:

bash 复制代码
docker run cloudflare/cloudflared:latest \
 tunnel --no-autoupdate run --token <TUNNEL_TOKEN>

这里的 <TUNNEL_TOKEN> 是 Cloudflare Dashboard 给当前 Tunnel 生成的令牌。

不要把真实 Token 发到博客、Git 仓库、截图或者聊天记录里。

如果 Token 泄露,应立即在 Cloudflare 侧进行处理,而不是继续使用泄露的凭据。

Cloudflare 官方文档给出的 Docker 运行方式也是通过 tunnel run --token 启动 remotely-managed tunnel。

更适合长期运行的 Docker Compose

如果希望让 cloudflared 跟随服务器自动启动,可以使用 Docker Compose:

yaml 复制代码
services:
 cloudflared:
 image: cloudflare/cloudflared:latest
 container_name: cloudflared
 restart: unless-stopped
 command: tunnel --no-autoupdate run --token ${CF_TUNNEL_TOKEN}

然后在 .env 中保存:

env 复制代码
CF_TUNNEL_TOKEN=这里填写真实Token

并确保 .env 不提交到 Git:

gitignore 复制代码
.env

如果你把整个项目提交到 Git,建议进一步使用密码管理器、Secrets 或 CI/CD Secret 来保存 Tunnel Token,而不是把它写进 compose 文件。


七、第四步:确认 Tunnel 已经连接

启动后回到 Cloudflare Dashboard:

text 复制代码
Networking
 → Tunnels
 → 你的 Tunnel

如果服务器上的 cloudflared 已经正常连上 Cloudflare,Tunnel 应该显示为正常/健康状态。

Linux 上也可以先看容器日志:

bash 复制代码
docker logs -f cloudflared

如果启动失败,优先检查:

bash 复制代码
docker ps

docker logs cloudflared

以及服务器能否正常访问互联网。


八、第五步:发布 API 域名

假设你家里的 Spring Boot API 在服务器本机的:

text 复制代码
http://127.0.0.1:8080

你希望公网访问:

text 复制代码
https://api.example.com

在 Cloudflare Dashboard 里进入对应 Tunnel,然后:

text 复制代码
Routes
 → Add route
 → Published application

然后填写:

text 复制代码
Hostname:
api.example.com

Service:
http://localhost:8080

保存即可。

Cloudflare 的 Published application 本质上就是建立一个"公网 Hostname → 本地 Service"的映射,例如 app.example.com → http://localhost:8080

如果你的服务不在 cloudflared 所在容器里

这里是 Docker 部署最容易踩坑的地方。

如果 cloudflared 自己是一个 Docker 容器,那么:

text 复制代码
http://localhost:8080

这里的 localhost 指向的是cloudflared 容器自己,不是宿主机。

如果你的 Spring Boot 运行在另一个 Docker 容器里,更推荐让两个容器进入同一个 Docker Network,然后直接通过容器服务名访问,例如:

text 复制代码
http://backend:8080

例如:

yaml 复制代码
services:
 backend:
 image: your-backend:latest
 restart: unless-stopped

 cloudflared:
 image: cloudflare/cloudflared:latest
 restart: unless-stopped
 command: tunnel --no-autoupdate run --token ${CF_TUNNEL_TOKEN}
 depends_on:
 - backend

这样 Cloudflare Tunnel 可以直接把请求交给 Docker 网络中的 backend:8080


九、如果前面还有 Nginx

如果你的家用服务器原本就已经使用 Nginx 做反向代理,那么结构可以设计成:

text 复制代码
Internet
 ↓
api.example.com
 ↓
Cloudflare
 ↓
Cloudflare Tunnel
 ↓
cloudflared
 ↓
Nginx
 ↓
Spring Boot

例如 Nginx:

nginx 复制代码
server {
 listen 80;
 server_name api.example.com;

 location / {
 proxy_pass http://backend:8080;
 proxy_set_header Host $host;
 proxy_set_header X-Real-IP $remote_addr;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 proxy_set_header X-Forwarded-Proto $scheme;
 }
}

然后 Cloudflare Tunnel 只需要指向 Nginx:

text 复制代码
http://nginx:80

这种方式的好处是:

  • Cloudflare 负责公网入口。
  • Tunnel 负责穿透。
  • Nginx 负责域名和反向代理。
  • Spring Boot 继续只承担业务接口。

如果后面有多个服务,会比较好管理。


十、DNS 需要怎么配置?

这里和传统公网 IP 的方式不一样。

传统情况可能是:

text 复制代码
A
api
203.0.113.10

但使用 Cloudflare Tunnel 后,不需要把家庭公网 IP 填进 A 记录

通过 Cloudflare Dashboard 创建 Published application 后,Cloudflare 会为这个 hostname 建立对应的 Tunnel 路由 / DNS 记录。

因此,最重要的不是"我家有没有公网 IP",而是:

text 复制代码
api.example.com
 ↓
Cloudflare Tunnel
 ↓
家里的 cloudflared

十一、这样之后还需要路由器端口转发吗?

通常不需要。

传统内网穿透经常要求:

text 复制代码
路由器 443
 ↓
服务器 443

Cloudflare Tunnel 的工作方式是家里服务器主动向外建立连接,所以通常不需要做公网入站端口映射,也不要求你拥有公网 IPv4。

因此家庭路由器可以保持:

text 复制代码
不开放 80
不开放 443
不开放其他业务端口

对于降低家庭网络暴露面是有帮助的。


十二、HTTPS 证书怎么办?

这也是 Cloudflare Tunnel 比单纯 FRP 更省事的地方。

用户访问:

text 复制代码
https://api.example.com

HTTPS 可以由 Cloudflare 在公网侧处理。

你家里的服务甚至可以继续使用:

text 复制代码
http://backend:8080

当然,如果你的内部链路还有额外安全要求,也可以继续使用 HTTPS。

Cloudflare Tunnel 的公网请求首先到 Cloudflare 网络,再通过 Tunnel 转到 origin;Cloudflare 在这个过程中可以应用其 CDN、WAF、Bot Management 和 DDoS 防护能力。


十三、一个完整的家庭服务器架构

如果家里服务器后面以后要跑很多东西,可以设计成:

text 复制代码
 Internet
 │
 https://api.example.com
 │
 ▼
 ┌───────────────┐
 │ Cloudflare │
 │ DNS / TLS / │
 │ WAF / DDoS │
 └───────┬───────┘
 │
 Cloudflare Tunnel
 │
 ▼
 ┌──────────────────┐
 │ cloudflared │
 └────────┬─────────┘
 │
 Docker Network
 │
 ┌────────────┴────────────┐
 │ │
 ▼ ▼
 Nginx other service
 │
 ▼
 Spring Boot API

以后还可以继续增加:

text 复制代码
api.example.com → Spring Boot
admin.example.com → 管理后台
home.example.com → 家庭网页
nas.example.com → NAS Web

不要因为 Tunnel 能转发,就把所有内部服务毫无保护地公开到公网。 管理后台、NAS、Docker 管理页面、数据库、MQTT 管理接口等,应根据实际需求增加访问控制。


十四、Cloudflare Tunnel 与 FRP 怎么选?

如果已经有一台公网 VPS,FRP 依然很有价值:

text 复制代码
公网 VPS
 ↑
 FRP
 ↑
家庭服务器

它的优势是控制力强、协议灵活,尤其适合你自己掌握公网中转服务器的场景。

Cloudflare Tunnel 则更适合:

text 复制代码
家里没有公网 IP
+ 已经有 Cloudflare 域名
+ 主要发布 HTTP/HTTPS 网站/API
+ 不想维护一台公网中转服务器

Cloudflare Tunnel 现在官方明确支持无公网 IP 的出站连接模式,并且 Tunnel 本身可以建立多条长期连接来提高可靠性。


十五、不要使用 Quick Tunnel 代替正式部署

Cloudflare 还提供 Quick Tunnel,例如:

bash 复制代码
cloudflared tunnel --url http://localhost:8080

它会生成一个随机的 trycloudflare.com 地址,非常适合临时测试。

但正式项目不建议长期使用 Quick Tunnel。Cloudflare 当前文档明确把 Quick Tunnels 定位为开发/测试用途,并且存在并发请求等限制。正式应用应该创建 Named / remotely-managed Tunnel。


十六、安全方面最容易犯的错误

1. 把 Tunnel Token 提交到 Git

错误:

yaml 复制代码
command: tunnel run --token eyJ......真实Token

然后直接提交 GitHub/Gitee。

正确:

yaml 复制代码
command: tunnel run --token ${CF_TUNNEL_TOKEN}

Token 放到 .env、Secrets 或其他安全凭据存储中。

2. 把数据库直接暴露出去

不要把:

text 复制代码
mysql:3306
redis:6379

直接发布成公网 hostname。

数据库应该继续留在内网,仅让后端 API 暴露出去。

3. 把 Docker 管理端口公开

例如 Docker API、Portainer、数据库管理页面、路由器后台等,应该谨慎处理。

4. 误以为"用了 Cloudflare 就不用认证了"

Cloudflare Tunnel 负责的是连接与入口,不代表业务本身自动安全。

例如:

text 复制代码
/api/login
/api/user
/api/order

仍然应该做好认证、授权、限流、参数校验等。


十七、排查问题时的顺序

https://api.example.com 打不开时,建议按照下面的链路一层层排查:

第 1 层:Cloudflare Tunnel 是否在线

bash 复制代码
docker ps | grep cloudflared
bash 复制代码
docker logs cloudflared

第 2 层:Tunnel 能不能访问内部服务

在服务器上测试:

bash 复制代码
curl http://127.0.0.1:8080

如果 Spring Boot 在 Docker 中,则测试实际 Docker 服务地址。

第 3 层:检查容器网络

例如:

bash 复制代码
docker exec -it cloudflared sh

然后测试目标服务是否可达。

第 4 层:检查 Cloudflare Published application

确认:

text 复制代码
Hostname:
api.example.com

Service:
http://backend:8080

是否填写正确。

第 5 层:检查应用层

例如:

bash 复制代码
curl -I https://api.example.com

如果能得到 HTTP 状态码,说明 DNS / Tunnel / 应用链路至少已经走通了一部分。


十八、最终推荐方案

对于"家庭服务器 + 没有公网 IP + 有自己的域名 + Docker + Spring Boot"这个场景,一个非常实用的方案是:

text 复制代码
 公网
 │
 ▼
 api.example.com
 │
 ▼
 Cloudflare
 │
 ▼
 Cloudflare Tunnel
 │
 (出站连接)
 │
 ▼
 家里的服务器
 │
 cloudflared
 │
 Docker 网络
 │
 ▼
 Nginx
 │
 ▼
 Spring Boot

核心特点:

  • 不要求家庭宽带有公网 IPv4。
  • 不需要家庭路由器做 443 入站端口转发。
  • 自己的域名可以继续使用。
  • HTTPS 公网入口由 Cloudflare 处理。
  • Docker 部署方便。
  • 后面可以继续挂多个子域名。

对于个人项目、家庭服务器、个人 API、博客、Demo 网站,这套方案非常适合。


十九、参考资料

本文以 Cloudflare 2026 年官方文档为依据:


二十、个人部署时的脱敏检查清单

发布文章、上传 Git 仓库或截图之前,建议检查:

text 复制代码
[ ] 真实域名 → 替换为 example.com
[ ] 真实公网 IP → 替换为 203.0.113.0/24 示例地址
[ ] 内网真实 IP → 替换为 192.168.x.x
[ ] Cloudflare Tunnel Token → 完全删除
[ ] API Key → 完全删除
[ ] Cloudflare Account ID → 删除或替换
[ ] Zone ID → 删除或替换
[ ] 路由器公网信息 → 删除
[ ] 个人邮箱 → 删除或替换
[ ] SSH 地址 / 端口 / 密码 → 删除
[ ] Docker Registry 地址 → 删除
[ ] 项目真实仓库地址 → 删除

原则:宁可让示例不完整,也不要为了"教程能复制"把真实凭据和真实基础设施信息贴出去。

相关推荐
智者向内寻求力量1 小时前
【记录】ubuntu 24.04 安装在levnoval PC上之后,蓝牙设备找不到解决方法
linux·服务器·ubuntu
halo雨航1 小时前
阿贝云免费服务器申请
运维·服务器
huainingning1 小时前
Linux和Windows系統SCP命令传输文件
linux·运维·服务器
幻步智能网络云专线1 小时前
幻步智能网络专线的优势
网络·网络协议
2401_862880821 小时前
Linux应用层开发 --- 多任务
linux·服务器·c语言
动力 continue1 小时前
MySQL 与网络基础 · 外键约束及 TCP/UDP 协议
网络·tcp/ip·mysql
bluesky9612221 小时前
服务器客户端开发异同
运维·服务器
智恒百亿2 小时前
AI服务器涨价15%背后:5090八卡智算服务器的选型与成本分析
大数据·服务器·人工智能·github
发量惊人的中年网工2 小时前
游戏开服就被DDoS攻击怎么办?开服7分钟服务器被打穿的复盘与防护清单
运维·服务器·网络·安全·游戏