块内指令(12 条)

cfd_tunnel { … } 一条隧道一个块。块里的配置只对这条隧道生效;模块级配置仍然是全局的。

nginx
cfd_tunnel {
    name               edge-a;                        # 只进日志
    token_file         /etc/nginx/cloudflared/a.token;
    inject_listen      127.0.0.1:8080;
    inject_source_addr 192.0.2.1;                     # 可选
    remote_config      on;                            # 可选
    host_override      app.internal;                  # 可选
    conn_index         0;                             # 可选
}
指令类型默认说明
namestr#序号只用于日志前缀(cfd_tunnel: [edge-a] …)
credentialsstr空凭据 JSON 路径;与 token / token_file / quick 四选一
tokenstr空这条隧道的 token(等价 cfd_tunnel_token,不 trim)
token_filestr空这条隧道的 token 文件(等价 cfd_tunnel_token_file,先 TrimSpace)
quickflagoffon = 这条隧道启动时申请临时地址
quick_servicestr继承模块级覆盖模块级同名配置
quick_timeoutmsec继承模块级覆盖模块级同名配置
inject_listenstr无注入目标:ip:port 或只写端口;开了 remote_config 可以不写
inject_source_addraddr继承模块级这条隧道的注入来源地址
remote_configflag继承模块级on = 接受边缘下发的远程配置
host_overridestr空注入请求的 Host 覆盖值(同时写 X-Forwarded-Host)
conn_indexnum按 worker注册时上报的 connIndex

块形式的语义细节 ​

  • 一个块 = 一条隧道 = 一份运行期状态(连接、流表、背压记账、定时器)。每 worker 一份 COW 拷贝。
  • 注入目标按隧道独立:inject_listen 解析出的 cfd_inject_target_t 传给注入器, 「请求按隧道送进对应 listen」的全部机制就是这一句。
  • 日志前缀:块隧道带 [名字] 或 [#序号],扁平那条不带 —— 所以 0.10.0 的日志断言一条都不用改。
  • 多对一是允许的:两条隧道指向同一个 listen 时并发注入安全(临时改监听器标志位的窗口是同步的), 但请求会落到该 listen 的默认 server,除非 Host 命中某个 server_name。
  • 失败隔离:凭据读不出 / 注入目标不存在 / 临时隧道申请失败 ⇒ 只跳过这一条, 其余隧道照常注册、照常服务。
  • 不能与扁平写法混用:写了任何一个 cfd_tunnel {} 之后,扁平那组 cfd_tunnel_* 若还出现, nginx -t 直接失败(inject_source_addr / quick_service / quick_timeout 除外, 它们本来就是「模块级一份 + 块内可覆盖」)。

只写端口的 inject_listen ​

nginx
cfd_tunnel { name a; quick on; inject_listen 8090; }

模块会在该端口的监听地址里找唯一的那一个;如果端口上同时存在多个监听地址 (例如 127.0.0.1:8090 与 0.0.0.0:8090),判「有歧义」并单独跳过这条隧道, 日志里说明原因 —— 不猜。

模块文档 · 对齐依据是 cloudflared 的源码与实测行为