Python 3.10+编译报错ssl缺失:怎么升级OpenSSL版本

拾光
拾光
发布时间:2026-11-07 | 3人浏览过
原创

针对从源码编译安装Python 3.10及以上版本时常见的_ssl模块构建失败、缺少OpenSSL 1.1.1+支持报错,提供从原因排查、独立编译升级OpenSSL到正确链接并成功安装Python的完整解决指南。

在 CentOS 7 或 Ubuntu 18.04 等较旧的 Linux 系统中从源码编译 Python 3.10 或更高版本时,如果终端提示 Could not build the ssl module 或安装后 import ssl 抛出 ModuleNotFoundError,根本原因在于 Python 3.10+ 将最低的加密库门槛提升至 OpenSSL 1.1.1。旧系统随附的 OpenSSL 1.0.2 无法满足构建要求。本文将带你通过“在独立目录编译较新版 OpenSSL,并在构建 Python 时显式指定路径”的方式,彻底解决这一报错,同时确保不破坏宿主系统的稳定运行。

一、明确报错根源:为什么 Python 3.10+ 编译会丢失 SSL

很多开发者在执行 ./configure && make && make install 时,整个过程并未直接中断退出,而是在结尾的模块构建摘要中出现了一行警告:

编译阶段典型警告输出(示例):
The following modules found by configure are missing a prerequisite:
_ssl

Python build finished successfully!
The necessary bits to build these optional modules were not found:
_ssl                  _hashlib

当你尝试运行编译好的 Python 时,只要调用依赖网络或加密的工具(例如 pip install),就会抛出明确的异常:No module named '_ssl'。

这是因为 Python 的官方标准库 ssl 模块底层依赖 C 语言扩展 _ssl.c。从 Python 3.10 起,核心团队出于网络通信安全考虑,正式废弃了对 OpenSSL 1.0.2 及更早版本的兼容支持,强制要求系统提供 OpenSSL 1.1.1 或更高版本(亦支持 LibreSSL 2.8.4+)。如果系统的 OpenSSL 版本停留在 1.0.2,配置脚本检测后就会自动跳过 _ssl 的编译,导致最终生成的 Python 缺少安全套接字支持。

Python 3.10+编译报错ssl缺失:怎么升级OpenSSL版本
图 1:Python 3.10+ 构建体系对底层 OpenSSL 版本的判定逻辑

二、容易混淆的认知:必须替换系统的 OpenSSL 吗?

在排查该问题时,常见的一种直觉是直接把系统的 OpenSSL 全局覆盖更新(例如将新版编译后强行覆盖 /usr/bin/openssl 和 /usr/lib64/libssl.so)。这种做法看似省事,实则隐藏了较大风险。

这种说法之所以看似合理,是因为我们通常习惯让全局环境保持最新。但在 CentOS 或 RHEL 等企业级 Linux 发行版中,系统的核心组件(如 yum、rpm、sshd、systemd)均紧密链接在系统自带的特定 ABI 版本(如 libssl.so.10)上。直接全局替换或修改动态链接库软链接,极易引发符号找不到的问题,导致系统包管理器无法打开,甚至造成远程 SSH 无法登录。

正确的应对原则是:环境隔离。我们将符合要求的新版 OpenSSL 编译安装到独立的非系统路径(例如 /usr/local/openssl11),仅在编译 Python 3.10+ 时通过配置参数告知其调用该路径,既达成了 Python 对加密库的升级需求,又完全不影响系统底层的稳定性。

Python 3.10+编译报错ssl缺失:怎么升级OpenSSL版本
图 2:为什么选用“独立目录安装”而非全局粗暴替换

三、核心操作步骤:从源码构建 OpenSSL 并重新编译 Python

下面演示在基于 RHEL/CentOS 7 体系下的完整操作流程。Ubuntu/Debian 体系原理相同,仅需调整包管理器命令。

Python 3.10+编译报错ssl缺失:怎么升级OpenSSL版本
图 3:四步完成安全升级与重编

步骤一:安装构建必需的基础工具与库

编译 OpenSSL 和 Python 之前,需确保环境内已安装编译器、Perl、压缩库及开发头文件。

# CentOS / RHEL 环境
sudo yum install -y gcc make perl perl-core zlib-devel bzip2-devel libffi-devel wget

# Ubuntu / Debian 环境对应命令
# sudo apt update && sudo apt install -y build-essential perl zlib1g-dev libffi-dev wget

步骤二:下载、编译并安装独立版 OpenSSL 1.1.1

此处以长期支持版本 OpenSSL 1.1.1w 为例。将其配置安装到独立前缀目录 /usr/local/openssl11 中。

cd /usr/local/src
sudo wget https://www.openssl.org/source/old/1.1.1/openssl-1.1.1w.tar.gz
sudo tar -zxvf openssl-1.1.1w.tar.gz
cd openssl-1.1.1w

# 配置:指定前缀,开启共享动态库 (shared),开启 zlib
sudo ./config --prefix=/usr/local/openssl11 --openssldir=/usr/local/openssl11 shared zlib

# 编译并安装
sudo make -j$(nproc)
sudo make install
关键参数说明
shared 表示生成 .so 动态共享库文件;--prefix=/usr/local/openssl11 确保文件集中存放在该自定义路径,不会覆盖宿主系统的 /usr/lib 或 /usr/bin。

步骤三:更新共享库缓存并验证 OpenSSL

为了让后续编译和运行时能顺利检索到该目录下的 libssl.so 和 libcrypto.so,向系统动态链接器添加一条独立配置:

# 写入 ld 配置文件
echo "/usr/local/openssl11/lib" | sudo tee /etc/ld.so.conf.d/openssl11.conf

# 刷新系统动态库缓存
sudo ldconfig -v | grep openssl11

# 验证二进制可用性与版本
/usr/local/openssl11/bin/openssl version
预期输出示例:
OpenSSL 1.1.1w  11 Sep 2023

步骤四:使用新 OpenSSL 重新配置与编译 Python 3.10+

回到 Python 源码根目录。如果之前已经执行过构建,请务必先执行 make distclean 清理缓存配置,然后使用 --with-openssl 明确指引路径。

cd /path/to/Python-3.10.x

# 清理历史构建残留
make distclean

# 显式指定 OpenSSL 目录与动态链接运行时路径 (rpath)
./configure --prefix=/usr/local/python3 \
            --with-openssl=/usr/local/openssl11 \
            --with-openssl-rpath=/usr/local/openssl11/lib \
            --enable-optimizations

# 编译并安装(建议使用 altinstall 避免覆盖系统预置 python 命令)
make -j$(nproc)
sudo make altinstall
为什么需要 --with-openssl-rpath?
参数 --with-openssl-rpath 会将 /usr/local/openssl11/lib 硬编码写入 Python 解释器的 ELF 文件 RPATH/RUNPATH 标记中。这样即使在未配置 LD_LIBRARY_PATH 的环境下执行 Python,它也能精准找到对应的 OpenSSL 动态库,杜绝运行期找不到库文件的隐患。

四、结果验证:确认 _ssl 模块与版本绑定

安装完成后,使用新编译的 Python 可执行文件进行交互式导入测试,查看所加载的底层库版本是否符合预期。

/usr/local/python3/bin/python3.10 -c "import ssl; print('OpenSSL Version:', ssl.OPENSSL_VERSION); print('Library Path:', ssl.__file__)"
预期终端输出:
OpenSSL Version: OpenSSL 1.1.1w  11 Sep 2023
Library Path: /usr/local/python3/lib/python3.10/ssl.py

随后验证包管理器 pip 是否能够正常建立 HTTPS 安全连接:

/usr/local/python3/bin/pip3.10 --version
/usr/local/python3/bin/pip3.10 install --upgrade pip

若能够正常下载并更新,说明 SSL 通信链路与证书体系已全部处于工作状态。

五、常见问题排查与注意事项

1. 执行 ./configure 时提示无法识别 --with-openssl-rpath
部分早期的 Python 3.10 补丁版本或部分环境下的 autoconf 脚本若不支持 --with-openssl-rpath,可以通过设置环境变量代替:
LDFLAGS="-Wl,-rpath,/usr/local/openssl11/lib" ./configure --prefix=/usr/local/python3 --with-openssl=/usr/local/openssl11
2. 运行 Python 时报:ImportError: libssl.so.1.1: cannot open shared object file
该错误表明动态链接器在标准路径下未能定位到 libssl.so.1.1。请检查:
  • 文件 /etc/ld.so.conf.d/openssl11.conf 是否已正确写入并包含了路径 /usr/local/openssl11/lib;
  • 是否以管理员权限运行了 sudo ldconfig;
  • 64位系统在极少数情况下会将库安装在 lib64 目录,可执行 ls /usr/local/openssl11 确认是 lib 还是 lib64,并对应修改路径。
3. 使用 pip 时提示 SSL: CERTIFICATE_VERIFY_FAILED
如果编译成功但访问网络时遇到证书认证错误,通常是旧系统的根证书包过期或路径不匹配所致。在 CentOS 下可通过重新安装 CA 证书链修复:
sudo yum reinstall -y ca-certificates && sudo update-ca-trust

六、核心要点总结

Python 3.10+编译报错ssl缺失:怎么升级OpenSSL版本
图 4:排查与修复流程核心机制总结

只要严格按照“独立编译较新版本 OpenSSL、正确注册动态链接库、使用 --with-openssl 重新引导 Python 编译”这一闭环流程处理,就能在完全不干扰宿主系统的环境下,顺利为 Python 3.10+ 装配完整的 SSL 支持。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表