命名隧道与多服务配置
Quick Tunnel 一行命令就能用,但 URL 每次都变,一条命令也只能暴露一个服务。要把本地服务长期稳定地暴露到自己的域名下,并且同时映射多个服务,就要用命名隧道。命名隧道配合 config.yml 配置文件,能精确控制每条路由指向哪个本地服务,是生产场景的标准做法。
命名隧道与 Quick Tunnel 的区别
| 对比项 | Quick Tunnel | 命名隧道 |
|---|---|---|
| 是否要登录 | 不需要 | 需要 cloudflared login |
| 是否要域名 | 用 trycloudflare.com | 绑定自己域名 |
| URL 稳定性 | 每次启动变化 | 固定不变 |
| 多服务支持 | 一条命令一个服务 | 一个隧道映射多个服务 |
| 配置方式 | 命令行参数 | config.yml 配置文件 |
| 适合场景 | 临时演示 | 长期生产 |
命名隧道的关键变化是有了持久化身份,隧道有名字、有 UUID,Cloudflare 侧记录它的路由规则,重启后身份不变。
创建命名隧道
确保已经登录过 Cloudflare 账号
cloudflared tunnel login
创建一条隧道,名字自定义
cloudflared tunnel create demo-tunnel
命令执行后会输出一个 UUID,形如
Created tunnel demo-tunnel with id 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
这个 UUID 是隧道的永久标识,凭据文件保存在 ~/.cloudflared/7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d.json。
列出已有隧道
cloudflared tunnel list
删除隧道
cloudflared tunnel delete demo-tunnel
config.yml 配置文件
命名隧道的路由规则写在 config.yml 里,默认路径 ~/.cloudflared/config.yml。一个最小配置
tunnel: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
credentials-file: /root/.cloudflared/7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d.json
ingress:
- hostname: app.example.com
service: http://localhost:8080
- service: http_status:404
字段说明
| 字段 | 作用 |
|---|---|
| tunnel | 隧道 UUID |
| credentials-file | 凭据文件路径,创建隧道时生成 |
| ingress | 路由规则列表,按顺序匹配 |
| hostname | 匹配的域名 |
| service | 匹配成功后转发的本地服务地址 |
| http_status:404 | 兜底规则,未匹配的请求返回 404 |
ingress 规则按从上到下顺序匹配,最后一条必须是不带 hostname 的兜底规则,否则 cloudflared 启动会报错。
多服务映射
一个隧道可以同时暴露多个服务,只要在 ingress 里加多条规则。假设本地跑着前端、后端 API、管理后台三个服务
tunnel: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
credentials-file: /root/.cloudflared/7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d.json
ingress:
- hostname: www.example.com
service: http://localhost:3000
- hostname: api.example.com
service: http://localhost:8080
- hostname: admin.example.com
service: http://localhost:9000
- service: http_status:404
三条规则分别把三个子域名映射到三个本地端口
| 域名 | 转发到 | 用途 |
|---|---|---|
| www.example.com | localhost:3000 | 前端 |
| api.example.com | localhost:8080 | 后端 API |
| admin.example.com | localhost:9000 | 管理后台 |
所有流量都走同一条隧道,不需要为每个服务单独建隧道。
路径路由
除了按域名分发,还能按路径在同一域名下分发
ingress:
- hostname: app.example.com
path: /api
service: http://localhost:8080
- hostname: app.example.com
service: http://localhost:3000
- service: http_status:404
| 请求 | 命中规则 | 转发到 |
|---|---|---|
| app.example.com/api/users | 第一条 | localhost:8080 |
| app.example.com/ | 第二条 | localhost:3000 |
| other.example.com/ | 兜底 | 返回 404 |
path 匹配是前缀匹配,/api 会匹配 /api、/api/users、/api/v1/xxx 等所有以 /api 开头的路径。
自定义域名绑定
隧道配置好路由后,还要把域名解析到这条隧道。cloudflared 提供了一条命令自动写 DNS 记录
cloudflared tunnel route dns demo-tunnel app.example.com
这条命令会在 Cloudflare DNS(Cloudflare 的域名解析服务)里为 app.example.com 添加一条 CNAME 记录,指向 demo-tunnel 的 UUID.cfargotunnel.com,无需手动改 DNS。
前提是 example.com 已经托管在 Cloudflare DNS 上。如果域名 DNS 不在 Cloudflare,要么把域名 NS 改到 Cloudflare,要么手动添加 CNAME 记录指向
多服务时为每个 hostname 都执行一次
cloudflared tunnel route dns demo-tunnel www.example.com
cloudflared tunnel route dns demo-tunnel api.example.com
cloudflared tunnel route dns demo-tunnel admin.example.com
启动隧道
配置和 DNS 都就绪后启动
cloudflared tunnel run demo-tunnel
或者直接用配置文件启动,不指定隧道名
cloudflared tunnel --config ~/.cloudflared/config.yml run
启动后日志里看到 Registered tunnel connection 表示连接建立成功,此时访问配置的域名就会转发到本地服务。
配置校验
配置写错容易导致启动失败,先校验
cloudflared tunnel ingress validate
常见错误
| 错误信息 | 原因 |
|---|---|
| The last ingress rule must not have a hostname | 缺少兜底规则 |
| No ingress rules were provided | ingress 段为空 |
| hostname is required | 规则缺少 hostname 或 service |
| credentials-file not found | 凭据文件路径不对 |
服务类型扩展
service 字段除了 http 还支持其他协议
| service 值 | 用途 |
|---|---|
| http://localhost:8080 | HTTP 服务 |
| https://localhost:8443 | HTTPS 服务,可加 originRequest 控制 TLS |
| tcp://localhost:22 | TCP 服务,需配合 cloudflared access |
| unix:/tmp/app.sock | unix socket |
| http_status:404 | 直接返回 404,用于兜底 |
HTTPS 后端要跳过证书校验时
ingress:
- hostname: app.example.com
service: https://localhost:8443
originRequest:
noTLSVerify: true
- service: http_status:404
originRequest 控制到本地服务的连接行为,常用字段
| 字段 | 作用 |
|---|---|
| noTLSVerify | 是否跳过 HTTPS 后端证书校验 |
| connectTimeout | 连接本地服务超时时间 |
| httpHostHeader | 转发时改写 Host 头 |
| originServerName | TLS SNI 名称 |
小结
命名隧道通过 UUID 持久化身份,配合 config.yml 灵活映射多个服务到多个域名。ingress 规则按顺序匹配,最后必须有不带 hostname 的兜底。DNS 解析用 cloudflared tunnel route dns 自动写入。这套配置足够支撑中小规模的多服务暴露场景。下一篇讲怎么给这些暴露出去的服务加身份验证,不是谁拿到域名都能进。
上一篇 内网穿透基础
下一篇 Access 身份访问控制