JavaLYG

Nginx 升级修复 CVE-2026-42533:map 正则漏洞从排查到平滑上线 1.30.4

一查版本才发现自己踩在雷区上:nginx -v 显示的是 nginx/1.26.3,而 F5/NGINX 官方最新的安全公告里,这个版本正落在受影响区间。这次修的是 CVE-2026-42533——map 指令搭配正则匹配时,worker 进程会触发一个堆缓冲区溢出。下面我把这次的版本判断、升级到 1.30.4/1.31.3 的完整流程、失败分支和回滚方案都梳理出来,照着做基本不会翻车。

一、这次官方到底修了哪些洞

nginx.org 的安全公告是权威来源,最近一次稳定版 1.30.4 和主线版 1.31.3 集中修了三个 CVE:

  • CVE-2026-42533:map 与正则匹配时的缓冲区溢出,官方标为 major(严重),CVSS 3.1 评分 8.1、CVSS 4.0 评分 9.2。
  • CVE-2026-60005ngx_http_slice_module 的内存泄漏,medium
  • CVE-2026-56434ngx_http_ssi_module 的释放后使用(use-after-free),medium

这三个都修在同一个版本里,所以只要升到 1.30.4+(stable)或 1.31.3+(mainline)就一次到位,不用来回折腾。

二、CVE-2026-42533 到底是什么

一句话说清楚:map 指令里如果用了正则匹配,而字符串表达式里 在引用 map 的输出变量之前,先引用了它的正则捕获变量,就会把数据写进一个已经算错大小的堆内存里。攻击者不需要登录,只要构造好特定的 HTTP 请求,就能让 worker 进程堆溢出然后崩溃重启——造成拒绝服务(DoS)。当系统关闭了 ASLR 或攻击者能绕过 ASLR 时,甚至可能升级成代码执行。

关键点:这是纯粹的数据面(data plane)问题,不涉及控制面,也就是说 Nginx 的管理配置面不被暴露。再看 CVSS 向量 AV:N/AC:H,攻击面确实在网络侧,但复杂度被标成了高——意思是它不会像随手一个请求那样每次都稳定生效,往往要求你的配置正好写成那种“先引用捕获变量”的形态,攻击者还要配合一些自己控制不了的条件。正因为如此,靠“最近没报错就等于安全”这种判断是站不住的,版本升级才是唯一干净的出路。

三、先确认你自己的版本

# 看版本号(小写 v 只给版本,大写 V 连编译参数一起给)
nginx -v
nginx -V

# 如果是自己编译或装在非 PATH 目录,用完整路径
/www/server/nginx/sbin/nginx -v

我这边跑出来就是 nginx/1.26.3。注意:版本号只是第一步,nginx -V 里还能看到是否编译了 --with-http_v3_module--with-http_rewrite_module 这些模块,后面升级时要用这些参数。想再精确点,把配置里所有 map 段捞出来看一眼:

# 找出所有 map 指令,再看是否有正则捕获组的用法
grep -rn "map " /path/to/nginx/conf/ | grep -v '#'
# 逐条看:是否用了正则,并且字符串表达式里在 map 输出变量之前引用了捕获变量

如果你的配置里一条“map + 正则”都没有,那这条洞在你这里的触发面基本为零——但版本还是建议跟齐,因为你没法保证后续不会被人加进去。

四、你到底受影响吗?对照一下

按官方公告,Nginx Open Source 的受影响范围分两段(历史上有一个版本号区间断开是因为分支切换):

状态版本区间
受影响0.9.6 至 1.30.3
受影响1.31.0 至 1.31.2
已修复(stable)1.30.4 及以上
已修复(mainline)1.31.3 及以上

NGINX Plus 商业版同样受影响:R33、R36 之前版本、以及 37.0.0.1 之前版本都需要补到对应修复版(R36 P7 / 37.0.3.1)。1.26.3 就落在 “0.9.6 至 1.30.3” 这一段里,属于需要重点关注的版本。

五、升级前必须先备份

# 备份整个配置目录,文件名带上日期
cp -r /path/to/nginx/conf "/path/to/nginx/conf.bak.$(date +%F)"

# 如果用了二进制替换,先备份原二进制
cp -p /path/to/nginx/sbin/nginx /path/to/nginx/sbin/nginx.bak.$(date +%F)

这一步不能省。升级最大的风险不是下载失败,而是新版本配置不兼容导致 nginx -t 都过不去。有备份心里就有底。要是配置本身在 git 里托管,顺手 commit 一下更稳妥——回滚直接看历史 diff,比手抄文件不容易出错。

六、三条升级路线怎么选

路线 A:源码编译(可控、参数全)
先记录旧版的 nginx -V 编译参数,下载对应版本的 tarball,然后按原参数来一遍:

# 解压后进入目录
./configure --prefix=/usr/local/nginx --with-http_ssl_module \
            --with-http_v2_module --with-http_v3_module \
            --with-http_stub_status_module --with-stream
make -j$(nproc)
make install

# 确认新版本和编译参数
/usr/local/nginx/sbin/nginx -V

路线 B:系统包管理器
Debian/Ubuntu 用 sudo apt update && sudo apt install nginx,RHEL/CentOS 用 sudo yum install nginxdnf。注意大多数发行版仓库里的版本偏旧,想拿 1.30.4 建议加官方 repo 或直接源码。

路线 C:面板一键升级
如果用的是宝塔这类面板,直接在软件商店里选 Nginx,看是否有 1.30.4+ 可切换,点升级即可。面板会自动处理配置迁移,但升级后仍要自己跑一遍 nginx -t 和重载。

七、配置校验与平滑重载

# 先校验,确认没有任何语法或模块报错
nginx -t

# 通过后再平滑重载,不中断已有连接
nginx -s reload

# 本地探活
curl -s -o /dev/null -w "%{http_code}\n" https://your-domain.example/

一定要先 nginx -treload。如果直接 reload 而配置有错,Nginx 会用旧配置继续跑但日志报错;更糟的是某些场景下 master 加载失败会直接影响新进程。

八、升级失败怎么办(故障分支)

现象可能原因处理
nginx -t 报配置错误新版本指令/模块变化对照备份 diff 配置,恢复旧配置后再排查
worker 启动即崩溃编译参数少了模块对比旧版 nginx -V,补全缺失的 --with-*
升级后访问 502/503反向代理上游或 socket 未跟上检查 upstream、fastcgi/php socket 是否仍在监听
HTTP/3 连不上--with-http_v3_module重新编译带上 v3 模块
回滚——还原备份配置与旧二进制,重新 nginx -t && nginx -s reload

九、验收清单

  1. nginx -v 确认新版本为 1.30.4+1.31.3+
  2. nginx -V 确认关键模块(ssl、v2、v3、rewrite、stub_status)都在。
  3. nginx -t 输出 syntax is ok 且无告警。
  4. 页面(首页+HTTPS)访问返回 200,静态资源正常。
  5. 日志里没有 segfaultworker process exited 之类的错误。
  6. 后续用一段时间,确认无新崩溃或连接异常。

十、小结

安全公告这种“升级到 xxx 版本”的建议,最容易被大家当耳边风,因为很多服务器一跑就是好几年不升级。但像 CVE-2026-42533 这种库溢出问题,只要你的 Nginx 在受影响区间、又恰好有对应的 map 正则配置,理论上就是被点名的。这次的关键就三点:先查版本、先备份、先 nginx -t 再 reload。保持订阅 nginx.org 的安全公告,比出事了再救要省心得多。

CVE-2026-42533 概要表格图
Nginx 安全版本升级流程图

🔕 评论已关闭