Ubuntu 下 nginx-1.24.0 源码分析 - ngx_ssl_version 函数

定义

event\ngx_event_openssl.h 中:

复制代码
#if (OPENSSL_VERSION_NUMBER >= 0x10100001L)

#define ngx_ssl_version()       OpenSSL_version(OPENSSL_VERSION)

#else

#define ngx_ssl_version()       SSLeay_version(SSLEAY_VERSION)

#endif
复制代码
#if (OPENSSL_VERSION_NUMBER >= 0x10100001L)

预处理指令,用于条件编译 ,

检查 OPENSSL_VERSION_NUMBER 是否大于或等于 0x10100001L(OpenSSL 1.1.0 版本对应的十六进制常量)

根据 OpenSSL 的版本号,决定使用不同的版本获取函数。这是为了确保代码与不同版本的 OpenSSL 兼容

OpenSSL 的版本号是通过一个宏 OPENSSL_VERSION_NUMBER 来表示的,这个宏的值是一个十六进制常量,它编码了 OpenSSL 的版本信息。
OpenSSL_version() 是 OpenSSL 1.1.0 新增的 API,用于获取版本信息。

OPENSSL_VERSION 是参数,表示需要获取完整的版本字符串

OPENSSL_VERSION_NUMBER

定义在 event\ngx_event_openssl.h

复制代码
#if (defined LIBRESSL_VERSION_NUMBER && OPENSSL_VERSION_NUMBER == 0x20000000L)
#undef OPENSSL_VERSION_NUMBER
#if (LIBRESSL_VERSION_NUMBER >= 0x2080000fL)
#define OPENSSL_VERSION_NUMBER  0x1010000fL
#else
#define OPENSSL_VERSION_NUMBER  0x1000107fL
#endif
#endif

这段代码是 Nginx 源码中用于处理 LibreSSL 和 OpenSSL 版本兼容性问题的部分。

复制代码
#if (defined LIBRESSL_VERSION_NUMBER && OPENSSL_VERSION_NUMBER == 0x20000000L)

defined LIBRESSL_VERSION_NUMBER

检查是否定义了 LIBRESSL_VERSION_NUMBER 宏。

这个宏通常在使用 LibreSSL 的时候会被定义,表明当前环境使用的是 LibreSSL 而非 OpenSSL。

OPENSSL_VERSION_NUMBER == 0x20000000L

检查 OPENSSL_VERSION_NUMBER 是否等于 0x20000000L

这个常量可能是一个特殊的占位值或标识符,通常用于区分 LibreSSL 和 OpenSSL 的版本

第三方库 openssl/opensslv.h 中定义了 OPENSSL_VERSION_NUMBER

用以下代码去输出它的值:

复制代码
#include <stdio.h>
#include <openssl/opensslv.h>

int main() {
    printf("OPENSSL_VERSION_NUMBER: 0x%lx\n", OPENSSL_VERSION_NUMBER);
    return 0;
}

没有 LIBRESSL_VERSION_NUMBER 的定义

#if (defined LIBRESSL_VERSION_NUMBER && OPENSSL_VERSION_NUMBER == 0x20000000L)

条件不成立

OPENSSL_VERSION_NUMBER 的值还是 0x30000020

#if (OPENSSL_VERSION_NUMBER >= 0x10100001L)

这个条件就成立

于是 ngx_ssl_version 的定义是这个

复制代码
#define ngx_ssl_version()       OpenSSL_version(OPENSSL_VERSION)

可用以下代码查看 OPENSSL_VERSION 的值:

复制代码
#include <stdio.h>
#include <openssl/crypto.h>

int main() {
    printf("OPENSSL_VERSION: %d\n", OPENSSL_VERSION);
    return 0;
}

用以下代码去使用以下 OpenSSL_version(OPENSSL_VERSION) 看一下效果

在编译时,需要使用 -lcrypto-lssl 选项来链接 OpenSSL 的库

复制代码
#include <stdio.h>
#include <openssl/crypto.h>
#include <openssl/opensslv.h>

int main() {
    printf("OPENSSL_VERSION: %s\n", OpenSSL_version(OPENSSL_VERSION));
    return 0;
}
复制代码
#undef OPENSSL_VERSION_NUMBER

取消定义 OPENSSL_VERSION_NUMBER

如果满足前面的条件(即当前环境是 LibreSSL 并且 OPENSSL_VERSION_NUMBER 被设置为 0x20000000L),则取消它的定义。这是因为需要重新定义 OPENSSL_VERSION_NUMBER 为一个更合理的值,以适应 Nginx 的版本检查逻辑

复制代码
#if (LIBRESSL_VERSION_NUMBER >= 0x2080000fL)

LIBRESSL_VERSION_NUMBER >= 0x2080000fL

检查 LibreSSL 的版本号是否大于或等于 0x2080000fL

如果 LibreSSL 的版本号足够新,则执行接下来的代码块。这个版本号的编码格式通常与 LibreSSL 的内部版本表示有关,0x2080000fL 对应的是一个特定的 LibreSSL 版本。

复制代码
#define OPENSSL_VERSION_NUMBER  0x1010000fL

定义 OPENSSL_VERSION_NUMBER0x1010000fL

如果 LibreSSL 的版本号 >= 0x2080000fL,则将 OPENSSL_VERSION_NUMBER 设置为 0x1010000fL。这个值对应的是 OpenSSL 1.1.0 的版本号(或者类似的功能集合),目的是让 Nginx 在处理 LibertySSL 的时候,能够伪造成 OpenSSL 1.1.0 的版本,从而兼容某些依赖于 OpenSSL 版本号的逻辑。

复制代码
#else

预处理指令,表示如果第 3 行的条件不成立(即 LibreSSL 的版本号 < 0x2080000fL),则执行接下来的代码块

复制代码
#define OPENSSL_VERSION_NUMBER  0x1000107fL
相关推荐
梦在深巷、1 小时前
nginx配置之负载均衡
运维·nginx·负载均衡
iRayCheung1 小时前
Kind方式部署k8s单节点集群并创建nginx服务对外访问
nginx·kubernetes·kind
xiaobin889992 小时前
【2025最新版】VMware虚拟机下载安装教程 保姆级图文详解(附安装包+常用镜像Linux,win11,ubuntu,centos)
linux·其他·ubuntu·centos
ALex_zry2 小时前
Ubuntu 20.04 C++开发环境搭建指南(2025版)
linux·c++·ubuntu
是大强5 小时前
ssl 中 key 和pem 和crt是什么关系
网络·网络协议·ssl
木下-俱欢颜15 小时前
搭建基于chrony+OpenSSL(NTS协议)多层级可信时间同步服务
运维·网络安全·udp·ssl
Eric.Lee202116 小时前
Ubuntu shell指定conda的python环境启动脚本
python·ubuntu·conda·shell
影龙帝皖18 小时前
Linux服务之lvs+keepalived nginx+keepalived负载均衡实例解析
linux·nginx·lvs
dubochao_xinxi21 小时前
✅ TensorRT Python 安装精简流程(适用于 Ubuntu 20.04+)
开发语言·python·ubuntu
yangshuo12811 天前
风车OVF镜像:解放AI开发限制的Ubuntu精简系统
linux·人工智能·ubuntu