FAQ

为什么要做成 nginx 模块,而不是再起一个 cloudflared? ​

因为「多一个进程」意味着多一份配置、多一条要盯的 systemd 单元、多一层要把请求再从本机端口转发 一次。做成模块后:凭据在 nginx 配置里、日志在 nginx 的 error_log 里、请求一进来就是 nginx 的 普通请求(server_name / location / proxy_pass 直接生效)。

代价是明确接受项目约束:只走 HTTP/2 到边缘、不改 nginx 源码、不引入额外进程 / 共享内存 / UDS。

为什么只支持 HTTP/2? ​

项目约束之一。边缘与 quick service 都必须协商 ALPN=h2;没协商到就明确失败,不做 HTTP/1.1 回退 —— 回退会让「看起来能用」的行为掩盖协议实现里的真实问题。

为什么裸 TCP 直接丢弃? ​

用户定案不做。模块的注入点在 nginx 的 HTTP 链上,承载不了任意字节流;静默降级成 HTTP 是 绝不能做的(会把「连不上」变成「连上了但字节被当 HTTP 解析」)。判据与 cloudflared 一致 (Cf-Cloudflared-Proxy-Src 非空),处置是 RST_STREAM(REFUSED_STREAM)。

Token 和 credentials 文件有什么不同? ​

没有本质不同。token 是 base64(JSON),解开就是 {a,t,s[,e]},与凭据文件的三个字段一一对应。 0.14.0 起两种写法都收,三选一。

我贴的 token 明明对,为什么报「不是合法的 base64」? ​

内联 cfd_tunnel_token 不 trim(照抄 cloudflared 的 --token)。复制时带上的尾部空格/换行 会让 base64 非法。两个办法:删掉空白,或改用 cfd_tunnel_token_file(文件内容会先 TrimSpace)。

为什么 nginx -t 通过,启动后却说 token 错? ​

因为校验发生在 worker 启动期,与 cloudflared 一致(它也是连的时候才校验)。nginx -t 只检查 配置语法与互斥关系,不联网、不解 token。

一条隧道出错会不会影响别的隧道? ​

不会。凭据坏、注入目标不存在、临时隧道申请失败都只跳过那一条(日志带隧道名),其余隧道照常; nginx 本身也照常应答普通 HTTP。

多个 worker 会建多条连接吗? ​

会,每条隧道每个 worker 一条(connIndex = worker 槽位,可用 conn_index 指定)。 快速隧道例外:只由 0 号 worker 建(cloudflared 对 quick tunnel 固定 HaConnections=1)。

用了 realip 之后 deny 127.0.0.1 就不管用了? ​

对。realip 采纳头部之后,$remote_addr 变成 CF-Connecting-IP,所有按地址写的 allow/deny、 limit_req_zone/limit_conn_zone 都要按新语义重写。要么按新地址写,要么别配 inject_source_addr。

$remote_port 为什么是空的? ​

虚拟连接没有真实端口(端口恒为 0);realip 采纳头部之后也还是空 —— 头部里没有端口信息。

开了 remote_config 后,dashboard 上改 ingress 为什么本地没变化? ​

两件事要分开看:

  1. 本地写死的永远优先(注入端口、Host);
  2. http_status:NNN 例外:它表达「不进源站」,会压过本地端口直接应答。

另外 version <= 已应用版本 会被整个忽略(与 cloudflared 一致),dashboard 没抬版本号就看不到变化。

为什么远程配置里写 unix: 有时 502、有时又能用? ​

unix: / unix+tls: 是HTTP 服务(不是裸 TCP)。本模块不能 dial unix socket: 本地没写 inject_listen 时 502;本地写了 inject_listen 时按「本地即源站」注入本地 nginx, 而本地 nginx 自己 proxy_pass http://unix:/run/app.sock 就能跑通。

支持 ssh / rdp 吗? ​

不支持(裸 TCP)。用 cloudflared,或者别的方案。

支持多区域(FedRAMP 那种 e 字段)吗? ​

不支持。模块只按一个 cfd_tunnel_edge 连一个固定边缘;token 带 e 会在启动期直接报错, 不猜地址。

升级只需要 reload 吧? ​

不是。load_module 在配置解析之前发生,必须 restart。

文档里的「断言数」是怎么来的? ​

每支套件自己打印「通过 N 项,失败 0 项」,汇总在 .scratch/merge/regress0140.summary。 本页的数字来自那一轮实际运行,不是估计。

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