家宽 / NAT 后面的开发机想暴露一个服务出去,传统方案是路由器端口转发 +
动态 DNS。Cloudflare Tunnel(前身 Argo Tunnel)走反向通道:本地 cloudflared
守护进程主动连出,所有入站流量走 Cloudflare 边缘转发回来。
好处:
- 公网完全看不到你的源 IP
- 不需要在路由器 / 防火墙打洞
- 免费层支持自定义域名 + HTTPS 自动签发
下面把本地 http://127.0.0.1:8080 暴露成 myapp.example.com。
前提:example.com 已经托管在 Cloudflare。
1. 安装 cloudflared
# Debian/Ubuntu
curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg \
| sudo tee /etc/apt/trusted.gpg.d/cloudflare-main.gpg >/dev/null
echo "deb https://pkg.cloudflare.com/cloudflared $(lsb_release -cs) main" \
| sudo tee /etc/apt/sources.list.d/cloudflared.list
sudo apt update && sudo apt install -y cloudflared
2. 登录 + 创建隧道
cloudflared tunnel login
# 浏览器里选择 example.com,授权后会下载 cert.pem 到 ~/.cloudflared/
cloudflared tunnel create myapp
# 输出隧道 UUID 和凭据文件路径 ~/.cloudflared/<uuid>.json
3. 写配置
# ~/.cloudflared/config.yml
tunnel: <这里粘上面的 UUID>
credentials-file: /home/yourname/.cloudflared/<uuid>.json
ingress:
- hostname: myapp.example.com
service: http://127.0.0.1:8080
- service: http_status:404
最后一条 http_status:404 是兜底必填项,否则 cloudflared 拒绝启动。
4. 配 DNS
cloudflared tunnel route dns myapp myapp.example.com
# 在 Cloudflare DNS 表里自动写入一条 CNAME 指向 <uuid>.cfargotunnel.com
5. 跑起来(先前台测试)
cloudflared tunnel run myapp
另开终端 curl https://myapp.example.com/,能拿到本地服务的响应就成功。
6. 转为 systemd 服务
sudo cloudflared service install
sudo systemctl enable --now cloudflared
sudo journalctl -u cloudflared -f
service install 会把 ~/.cloudflared/ 整个复制到 /etc/cloudflared/,
并生成 unit。后续改配置改 /etc/cloudflared/config.yml 然后 restart。
多服务复用同一隧道
ingress: 是个列表,可以挂多个:
ingress:
- hostname: app.example.com
service: http://127.0.0.1:8080
- hostname: api.example.com
service: http://127.0.0.1:3000
- hostname: ssh.example.com
service: ssh://127.0.0.1:22 # 配合 cloudflared access ssh 用
- service: http_status:404
踩过的坑
- 配置里
credentials-file必须是 绝对 路径,相对路径在 systemd 下找不到。 - DNS 那条 CNAME 是 "proxied" 状态(橙云)才会走 tunnel;如果手动改成
灰云(DNS only),整个 tunnel 立刻 404。 - 隧道凭据
.json文件等于密码,泄露后任何人都能冒充你的隧道。
/etc/cloudflared/权限默认 700,不要随便改。
登录后参与评论。