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 为什么本地没变化?
两件事要分开看:
- 本地写死的永远优先(注入端口、
Host); 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。 本页的数字来自那一轮实际运行,不是估计。