一查版本才发现自己踩在雷区上: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-60005:
ngx_http_slice_module的内存泄漏,medium。 - CVE-2026-56434:
ngx_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 nginx 或 dnf。注意大多数发行版仓库里的版本偏旧,想拿 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 -t 再 reload。如果直接 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 |
九、验收清单
nginx -v确认新版本为1.30.4+或1.31.3+。nginx -V确认关键模块(ssl、v2、v3、rewrite、stub_status)都在。nginx -t输出syntax is ok且无告警。- 页面(首页+HTTPS)访问返回
200,静态资源正常。 - 日志里没有
segfault、worker process exited之类的错误。 - 后续用一段时间,确认无新崩溃或连接异常。
十、小结
安全公告这种“升级到 xxx 版本”的建议,最容易被大家当耳边风,因为很多服务器一跑就是好几年不升级。但像 CVE-2026-42533 这种库溢出问题,只要你的 Nginx 在受影响区间、又恰好有对应的 map 正则配置,理论上就是被点名的。这次的关键就三点:先查版本、先备份、先 nginx -t 再 reload。保持订阅 nginx.org 的安全公告,比出事了再救要省心得多。


🔕 评论已关闭