news 2026/9/14 12:10:12

Envoy HTTP/3 空指针崩溃排查:CVE-2026-48521 修复与 auto_config 上游正确配法指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Envoy HTTP/3 空指针崩溃排查:CVE-2026-48521 修复与 auto_config 上游正确配法指南

Envoy HTTP/3 空指针崩溃排查:CVE-2026-48521 修复与 auto_config 上游正确配法指南

【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy

Envoy 在使用 auto_config 按 ALPN 自动协商上游协议、且上游通告 HTTP/3 时,会因空指针解引用触发进程崩溃,对应 CVE-2026-48521。本文带你看崩溃现场、协议协商机制、源码风险点,以及修复与验证的正确路径。

一、先看这张事实卡

项目内容
漏洞编号CVE-2026-48521
安全公告GHSA-5vff-j9p4-38j3
触发组合上游集群使用auto_config(ALPN 自动协商)+ 上游以 HTTP/3 响应
直接影响进程异常终止(abnormal process termination),非优雅退出
根因空指针解引用(null dereference)
处置优先级高——使用 auto_config 且上游可能通告 HTTP/3 的实例应立即升级

原始修复记录在 changelogs/current/bug_fixes/http3__fixed-crash-due-to-null-deref.rst,目前挂在current未发布变更集里,属于 bug_fixes 类别。

二、网关进程崩溃,为什么值得半夜爬起来

Envoy 是边缘/中间/服务型代理,一个 worker 进程没了,不只是少了一个进程——它持有的每一条 TCP 和 QUIC 连接在途请求瞬间被切断,上游侧表现为超时或 5xx,下游侧表现为 503。对网关层来说,这就是全量流量受影响。

上面这张截图就是典型的上游集群端点视图:一个网关实例背后挂着若干个upstream集群和端点。任何一个实例崩掉,这些在途请求就没有宿主了。

排查时你会发现崩溃栈指向空指针解引用,而不是断言失败或异常退出——说明是某个指针在特定时序下根本没被赋值就被解引用了。这正是"配置合法、流量正常、偶发崩溃"这类问题的典型特征:它只在某条罕见的回调时序上命中。

三、Envoy 连上游时,到底怎么选协议

ALPN 自动协商:三个分支,一个回退规则

上游协议选择有三种配置分支,定义在 api/envoy/extensions/upstreams/http/v3/http_protocol_options.proto:

  • explicit_http_config:固定协议,写死 HTTP/1 或 HTTP/2,不参与协商;
  • use_downstream_protocol_config:跟随下游连接使用的协议;
  • auto_config(即AutoHttpConfig消息):靠 ALPN——应用层协议协商(Application-Layer Protocol Negotiation),TLS 握手里双方交换支持的协议清单——在 HTTP/1 与 HTTP/2 之间动态选择。

auto_config的回退规则很明确:上游不支持 ALPN 时直接落回 HTTP/1;传输层可以自定义 ALPN,但集群默认(或自定义失败时)用的是"h2,http/1.1"。⚠️ 这一分支只能用支持 ALPN 的传输套接字(一般是 TLS),否则配置加载直接失败。

HTTP/3 是个"条件参与者"

HTTP/1、HTTP/2 是"配置即生效",HTTP/3 不是。它要同时满足两个条件才上场:

  1. auto_config里写了http3_protocol_options(注意这个字段只表示"允许",不等于"启用");
  2. 上游明确通告了 HTTP/3 支持,通告来源是 HTTP Alt-Svc(RFC 7838 的替代服务协议头)或 HTTPS DNS 资源记录。

没有通告就老老实实用 HTTP/2 或 HTTP/1。这套设计的动机在 source/docs/http3_upstream.md 里讲得很直白:HTTP/3 跑在 QUIC 上,QUIC 基于 UDP,而 UDP 流量经常被中间网络设备拦截。所以 Envoy 必须做到两件事——在 UDP 被拦的死网络上,记住"HTTP/3 连不通"避免反复徒劳重试;在 UDP 正常的网络上,又别浪费一次 HTTP/2 握手。

回退与失败记忆:状态追踪器怎么记"这笔账"

记忆 HTTP/3 可用性的对象是Http3StatusTracker,现代实现见 source/common/http/http3_status_tracker_impl.cc。它维护四个状态:Pending(待定)、Broken(已损坏,进入退避)、FailedRecently(最近失败)、Confirmed(已确认可用)。

退避参数以源码为准:初始损坏期 1 秒(DefaultExpirationTime{1}),每次再次被标记损坏按1 << consecutive_broken_count_指数翻倍,连续损坏计数上限 17,也就是最长退避约 2^17 秒(约 36 小时);一旦走到Confirmed,计数归零、下次重新从 1 秒起。

⚠️ 这里有个对照值得记住:架构文档 source/docs/http3_upstream.md 写的是"首次损坏 5 分钟、再次翻倍、上限 1 天",但源码实现是"首次 1 秒、翻倍、上限 2^17 秒"。两者不一致,以源码为准——test/common/http/http3_status_tracker_impl_test.cc 的MarkBrokenWithBackoffMarkBrokenWithBackoffMax用例验证的就是 1s→2s→4s→8s 的指数序列和 2^17 秒封顶。

四、空指针最可能藏在哪三个位置

changelog 只说修了空指针解引用,没给补丁细节,以下是结合代码结构的推断,不是官方修复说明。

1.ConnectivityGrid双池的惰性创建与时序回调。source/common/http/conn_pool_grid.cc 里的ConnectivityGrid同时包着一个 QUIC 池(Http3ConnPoolImpl)和一个 TCP 混合池(HttpConnPoolImplMixed),两个池都是惰性创建的。请求分派时 HTTP/3 可用就走 QUIC 池,已标记 broken 则 TCP 立即并行发起,未通告 HTTP/3 直接进混合池;已通告且工作正常时,300ms(kDefaultTimeoutMs = 300)内没成功就向混合池再发一次,谁先成谁胜出。回调链(onPoolFailureonPoolReady、竞速超时定时器)里任何一处解引用了尚未创建的池成员,就是崩溃。

2. 状态追踪器依赖的缓存未就绪。追踪器挂在HttpServerPropertiesCache的 origin 上,实现见 source/common/http/http_server_properties_cache_impl.cc。这个缓存记录"哪些服务器通告了 HTTP/3",目前只存与请求同主机名、同端口的通告。缓存未建、origin 解析失败时,追踪器访问路径上的指针就是悬空的。

3. 配置层的兜底校验。source/extensions/upstreams/http/config.cc 里有一道硬闸:auto_confighttp3_protocol_options却没带alternate_protocols_cache_options时,配置加载直接报"alternate protocols cache must be configured when HTTP/3 is enabled with auto_config"。它堵住了"HTTP/3 开着但缓存缺失"这种静态错配,但运行时时序问题仍要靠代码判空来防。

五、怎么修:升级、配法、过滤器坑位与回归测试

第一优先级永远是升级——把跑在受影响集群上的实例升到包含 CVE-2026-48521 修复的版本。下面是配置侧要做的事。

一份能完整加载的集群 YAML。auto_config下三种协议选项缺一不可,alternate_protocols_cache_options是 HTTP/3 场景的必填项:

static_resources: clusters: - name: upstream_with_h3 connect_timeout: 5s type: STRICT_DNS load_assignment: cluster_name: upstream_with_h3 endpoints: - lb_endpoints: - endpoint: address: socket_address: address: upstream.example.com port_value: 443 transport_socket: name: envoy.transport_sockets.tls typed_config: "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext sni: upstream.example.com typed_extension_protocol_options: envoy.extensions.upstreams.http.v3.HttpProtocolOptions: "@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions auto_config: http_protocol_options: {} http2_protocol_options: {} http3_protocol_options: {} alternate_protocols_cache_options: name: default_alternate_protocols_cache max_entries: 1024

几个注意点:transport_socket必须是支持 ALPN 的 TLS 套接字,否则配置加载失败;缓存name用于标识缓存实例,跨配置组件引用同名缓存时各字段必须一致;max_entries默认 1024,实际条目数是近似值(每个 worker 独立执行);key_value_store_config持久化目前只在并发度为 1 时支持。

过滤器侧:启用 alternate_protocols_cache 过滤器。Alt-Svc 头要有人解析写进缓存,这个活由envoy.filters.http.alternate_protocols_cache干,挂在 HttpConnectionManager 的http_filters链里,typed_config指向envoy.extensions.filters.http.alternate_protocols_cache.v3.FilterConfig即可,不需要再填别的字段。

这里有个废弃字段的坑:api/envoy/extensions/filters/http/alternate_protocols_cache/v3/alternate_protocols_cache.proto 里的alternate_protocols_cache_options已标记deprecated(计划 3.0 移除),proto 注释明说该字段被忽略——过滤器直接使用请求所路由到的集群上声明的缓存。老配置里如果还在过滤器里填这个字段,删掉,改到集群auto_config上。

回归测试基线。两个目标要跑:bazel test //test/common/http:conn_pool_grid_test(覆盖双池竞速与回退链)和bazel test //test/common/http:http3_status_tracker_impl_test(覆盖状态迁移与退避)。test/common/http/conn_pool_grid_test.cc 里的Success用例验证"通告存在→QUIC 池→握手成功→Confirmed",DoubleFailureThenSuccessSerial验证"QUIC 池失败→交替池失败→HTTP/2 池成功→最终标 broken",后者正是修复所保护的那条不崩溃路径。

六、防复发检查清单

检查项为什么重要怎么查
auto_config 配置完整性三协议选项缺一个、缓存选项缺失都会导致行为异常或加载失败config_dump比对:三种协议选项齐全、alternate_protocols_cache_options存在且name与过滤器一致
UDP 可达性HTTP/3 依赖 UDP,被拦则回退链路长期承压,空指针修复前这条链路上最容易炸抓包看 QUIC 连接是否被丢;看集群 HTTP/3 连接成功/失败计数与 broken 退避行为
版本是否含修复进程崩溃不可接受,升级是唯一根治手段核对实例版本号 ≥ 发布含 CVE-2026-48521 修复的版本,对照 changelog 条目
回归测试基线升级后要保证回退与退避行为没退化CI 里跑//test/common/http:conn_pool_grid_test//test/common/http:http3_status_tracker_impl_test并确认通过

附录:文件索引

changelog

  • 修复条目:changelogs/current/bug_fixes/http3__fixed-crash-due-to-null-deref.rst

架构文档

  • 上游 HTTP/3 架构说明(含退避参数的文档口径):source/docs/http3_upstream.md

proto 定义

  • 上游协议选项与AutoHttpConfig:api/envoy/extensions/upstreams/http/v3/http_protocol_options.proto
  • AlternateProtocolsCacheOptions:api/envoy/config/core/v3/protocol.proto
  • 过滤器配置(含废弃字段):api/envoy/extensions/filters/http/alternate_protocols_cache/v3/alternate_protocols_cache.proto

核心实现

  • 双池路由与 300ms 竞速:source/common/http/conn_pool_grid.cc
  • HTTP/3 状态追踪器:source/common/http/http3_status_tracker_impl.cc
  • 通告缓存:source/common/http/http_server_properties_cache_impl.cc
  • 配置校验(HTTP/3 + auto_config 缓存必填):source/extensions/upstreams/http/config.cc

测试用例

  • 双池与回退链:test/common/http/conn_pool_grid_test.cc
  • 状态追踪与指数退避:test/common/http/http3_status_tracker_impl_test.cc
  • 通告缓存行为:test/common/http/http_server_properties_cache_impl_test.cc

【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 12:09:35

Ever® Gauzy™ 开源项目安装与使用教程

Ever Gauzy™ 开源项目安装与使用教程 【免费下载链接】ever-gauzy Ever Gauzy™ - Open Business Management Platform (ERP/CRM/HRM/ATS/PM) - https://gauzy.co 项目地址: https://gitcode.com/GitHub_Trending/ev/ever-gauzy 1. 项目的目录结构及介绍 Ever Gauzy™…

作者头像 李华
网站建设 2026/9/14 12:08:33

SpringBoot线程池配置优化与实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 12:07:38

Python环境配置与开发入门指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 12:04:16

SurfSense 前端 SVG 精度优化实战:用 SVGO 精简图标资源体积

SurfSense 前端 SVG 精度优化实战&#xff1a;用 SVGO 精简图标资源体积 【免费下载链接】SurfSense Open-source NotebookLM alternative. Research the open web with live data(Reddit, YT, IG, TikTok, Indeed, Google Search, Maps etc) through one platform, API or MCP…

作者头像 李华