关键在于切断编译时头文件与链接时库文件的错配路径:一、查清openssl命令位置、编译信息、pkg-config版本及所有头文件/库路径;二、显式指定--with-openssl-includes和--with-openssl-libraries,并加固cc-opt与ld-opt;三、禁用旧openssl.pc干扰;四、依报错提示判断版本兼容性(如engine_by_id弃用表明需nginx≥1.21适配openssl 3.x);五、用nginx -v和ldd验证实际绑定版本。

排查 Nginx 源码编译时的 OpenSSL 版本不兼容故障,关键在于切断“编译时头文件”和“链接时库文件”的错配路径。很多报错看似是代码问题,实则是 configure 阶段悄悄混用了旧头文件或新库,导致符号缺失、函数弃用警告甚至编译中断。
确认系统中 OpenSSL 的真实分布
别只信 openssl version ——它只反映命令行工具版本,不等于 Nginx 编译会用到的头文件和库。必须查清四类路径:
- 命令行 openssl 所在位置:which openssl
- 其编译信息与依赖库:openssl version -a && ldd $(which openssl) | grep ssl
- pkg-config 认定的版本:pkg-config --modversion openssl(configure 默认优先读它)
- 所有可能的头文件和库路径:find /usr /usr/local /opt -name "opensslv.h" 2>/dev/null 和 find /usr /usr/local /opt -name "libssl.so*" 2>/dev/null
强制指定编译路径,绕过 pkg-config 干扰
当系统存在多版本 OpenSSL(如 Ubuntu 22.04 自带 3.0,又手动装了 1.1.1w),configure 很容易被旧的 openssl.pc 带偏。必须显式绑定:
- 用 --with-openssl-includes=/path/to/include 指定头文件目录(不是源码根目录)
- 用 --with-openssl-libraries=/path/to/lib 指定动态库目录
- 追加编译与链接参数加固:--with-cc-opt="-I/path/to/include" --with-ld-opt="-L/path/to/lib -Wl,-rpath,/path/to/lib"
- 禁用 pkg-config 干扰:临时重命名或移走 /usr/lib/x86_64-linux-gnu/pkgconfig/openssl.pc
识别典型不兼容报错并对应处理
不同 OpenSSL 版本间 API 变动剧烈,报错提示其实很明确:
- undefined reference to SSL_CTX_set_ciphersuites → OpenSSL ssl_ciphersuites
- ‘ENGINE_by_id’ is deprecated: Since OpenSSL 3.0 → Nginx 1.21 之前版本不兼容 OpenSSL 3.x,需打补丁或降级 OpenSSL 至 1.1.1 系列
- SSL_library_init undeclared → 头文件版本太新(如 OpenSSL 3.x),但 configure 错配了旧库(如 1.1.1),或反之;检查 src/event/ngx_event_openssl.c 中是否条件编译失效
验证编译产物是否真正绑定目标 OpenSSL
编译成功不等于链接正确。安装后务必验证:
- 运行 nginx -V,确认输出中 built with OpenSSL xxx 与你指定的版本一致
- 执行 ldd $(which nginx) | grep ssl,看实际加载的是哪个 libssl.so
- 若用自定义路径(如 /opt/openssl-1.1.1w/lib),确保该路径在 /etc/ld.so.conf.d/ 中注册,或启动前设置 LD_LIBRARY_PATH











