必须重编译Nginx:先用nginx -V和ldd确认其静态链接OpenSSL,再选用OpenSSL 1.1.1w或3.0.13源码编译安装,最后严格按原参数重编译Nginx并完成语法、版本、TLS握手及业务四项验证。

遇到 OpenSSL 漏洞引发的生产故障,不能只升级 OpenSSL 库——如果 Nginx 是静态链接 OpenSSL(绝大多数自编译部署场景都是),旧版 OpenSSL 升级后对 Nginx 完全无效。必须重新编译 Nginx,并精确复用原有模块与配置逻辑,否则极易引发服务中断、SSL 握手失败或功能缺失。
先确认 Nginx 是否静态链接 OpenSSL
这是最关键的前置动作,跳过这步直接编译等于盲目操作:
- 执行 nginx -V(注意是大写 V),检查输出中是否含 --with-openssl=/xxx/openssl-xx。有即为静态编译;
- 运行 ldd $(which nginx) | grep ssl,若无任何 libssl.so 输出,说明未动态依赖系统 OpenSSL;
- 查进程打开文件:lsof -p $(pgrep nginx) | grep -i ssl,无结果也佐证静态链接。
选择匹配的安全 OpenSSL 版本并安装
不要盲目追新。生产环境推荐使用长期支持且已广泛验证的版本,例如 OpenSSL 1.1.1w(2023年11月发布,修复了包括 CVE-2023-0286 在内的多个高危漏洞)或 OpenSSL 3.0.13(2024年12月发布,兼容性更稳)。避免使用仍在 beta 或刚发布的版本。
- 下载源码后,在 /usr/local/src 解压,执行 ./config --prefix=/usr/local/openssl-1.1.1w --openssldir=/usr/local/openssl-1.1.1w shared zlib;
- make && make install 后,立即更新动态库路径:echo "/usr/local/openssl-1.1.1w/lib" >> /etc/ld.so.conf && ldconfig;
- 验证:/usr/local/openssl-1.1.1w/bin/openssl version 应返回准确版本,且 strings /usr/local/openssl-1.1.1w/lib/libssl.so.1.1 | grep "^OpenSSL" 确认无截断。
按原配置重编译 Nginx,不增不减
核心原则:复用 nginx -V 输出中的全部 configure arguments,仅将其中的 --with-openssl=旧路径 替换为新路径,其余参数一字不动。
- 进入 Nginx 源码目录(如 nginx-1.19.9),执行原参数 + 新 OpenSSL 路径,例如:
./configure --prefix=/usr/base-runtime/nginx --with-openssl=/usr/local/src/openssl-1.1.1w ...(其余保持原样); - 若原编译含第三方模块(如 ngx_cache_purge、headers-more),确保这些模块源码仍存在,且路径在 configure 中正确引用;
- 执行 make(无需 make install),编译完成后,objs/nginx 即为新二进制文件;
- 备份原 /usr/base-runtime/nginx/sbin/nginx,再用 objs/nginx 替换,chmod 755。
上线前必做的四项验证
替换后不能直接 reload,必须逐项确认:
- 语法检查:运行 /usr/base-runtime/nginx/sbin/nginx -t,确保配置无误;
- 版本核对:执行 /usr/base-runtime/nginx/sbin/nginx -V,确认 OpenSSL 路径已更新,且所有模块列表与之前一致;
- SSL 握手测试:用 openssl s_client -connect yourdomain.com:443 -tls1_2 验证能成功建立 TLS 1.2 连接,无 alert 报错;
- 业务连通性:调用关键接口(如登录、支付回调)、检查日志中是否有 SSL handshake failed 或 module not found 类错误。











