我现在更倾向于把家庭服务器的 Web 服务这样接到公网:
访客
↓
Cloudflare 边缘网络
↓
Cloudflare Tunnel
↓
家里的 cloudflared
↓
http://127.0.0.1:3000
核心变化只有一个:不再等待公网主动连接家里的路由器,而是让 cloudflared 从内网主动建立到 Cloudflare 的出站连接。
这对没有公网 IPv4、无法做端口映射,或者不希望直接暴露家庭出口地址的人很实用。但 Tunnel 不是“安装完就自动安全”的魔法。它只解决连接路径,应用自己的认证、授权和漏洞仍然要自己处理。
先分清公开服务和私人访问
公开网站、演示站、Webhook 接口,可以通过 Published application 映射到公开域名。
NAS 管理页、路由器后台、SSH、数据库等内部服务,不应该直接对所有访客开放。至少要叠加 Cloudflare Access 身份认证,或者改用 VPN/组网方案。
如果只是想远程打开自己的内网设备,直接照搬公开网站方案,通常是在解决一个问题的同时制造另一个问题。
开始前先验证本地服务
假设网站运行在本机 3000 端口,先执行:
curl -I http://127.0.0.1:3000
这里必须先返回正常结果。否则,即使 Tunnel 本身在线,Cloudflare 也只会把请求转发到一个无法访问的本地端口。
建议同时确认:
- 应用到底监听
127.0.0.1、0.0.0.0还是容器内部地址; - 宿主机和容器之间是否正确映射端口;
cloudflared运行的机器能否访问目标服务;- 本机是否已经存在另一套
cloudflared服务。
创建 Tunnel
在 Cloudflare 控制台进入:
Networking → Tunnels → Create Tunnel
创建一个便于识别的 Tunnel,例如 home-web,然后选择服务器对应的操作系统和架构。后台会给出安装命令,其中包含 Tunnel Token。
Token 不应该出现在截图、Git 仓库、聊天记录或公开日志里。拿到它的人可能运行新的连接器,接入你的 Tunnel。
安装完成后检查服务状态:
systemctl status cloudflared
journalctl -u cloudflared --no-pager -n 100
如果是 Docker 或其他安装方式,则使用对应的容器和进程日志检查。
把域名映射到本地端口
进入刚才创建的 Tunnel:
Routes → Add route → Published application
例如:
Hostname: app.example.com
Service URL: http://127.0.0.1:3000
保存后,请求 https://app.example.com 会经过 Cloudflare,再由 Tunnel 转发到本地 3000 端口。
如果目标服务在局域网另一台机器上,可以填写那台机器的内网地址。前提仍然是 cloudflared 所在主机能够直接访问该地址。
我会额外加的安全门槛
即使不开放路由器端口,应用仍然进入了公网访问路径。至少要做这些事:
- 管理界面增加可靠的登录和访问控制;
- 不公开数据库、Redis、Docker API 和路由器管理端口;
- Token 不进入 Git,并限制服务器配置文件权限;
- 更新应用依赖,修复应用本身的漏洞;
- 检查上传、注册、密码重置和调试接口;
- 保留 Tunnel 与应用日志,设置异常自动重启。
WAF、CDN 和隐藏源站地址都不能代替应用安全。Cloudflare Tunnel 减少的是公网入口和家庭网络配置,不是安全责任。
502 时不要先重装
排查顺序应该从内到外:
curl本地服务;- 检查应用监听地址和容器端口;
- 查看
cloudflared状态与日志; - 核对 Service URL 的协议、地址和端口;
- 最后再看域名、HTTPS 和 Cloudflare 后台状态。
很多 502 并不是 Tunnel 坏了,而是本地应用没有真正运行在你填写的地址上。
官方文档:
对于个人网站、开发预览和轻量公开服务,这套路径比申请公网 IP、配置 DDNS、开放端口更省事。对于私人管理服务,则要在 Tunnel 之上增加身份验证,而不是把它直接暴露出去。