CentOS 7 编译安装 Python 3.9 解决 SSL 模块缺失问题

在 CentOS 7 上从源码编译 Python 3.9 时,经常遇到 SSL 模块无法导入的问题,导致 pip 无法使用 HTTPS 源,甚至影响 Ansible 等工具的正常运行。本文汇总了常见错误信息,分析了根本原因,并提供了一套经过验证的完整解决方案,最终给出可直接使用的安装脚本。

1. 报错信息汇总

1.1 编译后无法导入 ssl 模块

复制代码
  >>> import ssl
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.9/ssl.py", line 98, in <module>
    import _ssl
ModuleNotFoundError: No module named '_ssl'

1.2 pip 操作提示 SSL 不可用

复制代码
  WARNING: pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.
Could not fetch URL https://pypi.org/simple/pip/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url: /simple/pip/ (Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available."))

1.3 Ansible 执行时因 SSL 问题失败

复制代码
  fatal: [192.168.233.128]: FAILED! => {"changed": false, "msg": "SSL validation is not available in your version of python. You can use validate_certs=False, however this is unsafe and not recommended"}

1.4 其他常见依赖缺失

  • zipimport.ZipImportError: can't decompress data; zlib not available
  • • 编译时提示找不到 OpenSSL 头文件或库

2. 问题原因分析

  • Python 3.9 要求 OpenSSL 1.1.1 或更高版本 ,而 CentOS 7 系统默认的 OpenSSL 版本为 1.0.2,且系统自带的 openssl-devel 包仅提供 1.0.2 的头文件和库。
  • • 即使通过 EPEL 安装了 openssl11-devel,由于系统默认的编译环境和链接器仍会优先查找 /usr/include/usr/lib64 下的旧版本,导致 Python 的 configure 脚本找不到正确的 OpenSSL 1.1.1,或者找到的是不兼容的旧版本,最终无法编译出 _ssl 模块。
  • • 简单指定 --with-openssl=/usr/include/openssl11 并不足够,因为该目录下没有完整的库文件结构(缺少 lib 子目录),且运行时链接可能依然指向旧库。

3. 解决方案

核心思路 :安装 OpenSSL 1.1.1 开发包,并通过 pkg-config 获取正确的编译和链接标志,将其传递给 Python 的构建系统。

3.1 安装 OpenSSL 1.1.1 开发包

CentOS 7 可以通过 EPEL 仓库安装 openssl11-devel,该包会提供 OpenSSL 1.1.1 的头文件、库文件以及 pkg-config 配置文件(openssl11.pc)。

复制代码
  sudo yum install -y epel-release
sudo yum install -y openssl11 openssl11-devel

3.2 使用 pkg-config 设置编译环境变量

在运行 Python 的 ./configure 脚本之前,导出 CFLAGSLDFLAGS 环境变量,让编译器和链接器知道去哪里找 OpenSSL 1.1.1 的头文件和库。

复制代码
  export CFLAGS="$CFLAGS $(pkg-config --cflags openssl11)"
export LDFLAGS="$LDFLAGS $(pkg-config --libs openssl11)"

pkg-config --cflags openssl11 会输出类似 -I/usr/include/openssl11 的选项,而 --libs 会输出 -L/usr/lib64/openssl11 -lssl -lcrypto 等。这样 Python 的构建系统就能正确找到 OpenSSL 1.1.1。

3.3 配置并编译 Python

执行配置时不需要 再使用 --with-openssl 参数,因为环境变量已经指定了路径。

复制代码
  ./configure --enable-optimizations --prefix=/usr/local/python3.9
make -j$(nproc)
sudo make altinstall

3.4 验证 SSL 模块

安装完成后,验证 SSL 模块是否可用:

复制代码
  /usr/local/python3.9/bin/python3.9 -c "import ssl; print(ssl.OPENSSL_VERSION)"

如果输出 OpenSSL 1.1.1 的版本号,则成功。

4. 完整版安装脚本

以下脚本整合了所有步骤,可直接复制粘贴到 CentOS 7 系统中执行(以 root 用户或使用 sudo)。

复制代码
  #!/bin/bash
# CentOS 7 编译安装 Python 3.9 并启用 SSL 模块

set -e  # 遇到错误立即退出

# 1. 安装系统依赖和 OpenSSL 1.1.1
yum install -y epel-release
yum groupinstall -y "Development Tools"
yum install -y openssl11 openssl11-devel \
    zlib-devel bzip2-devel ncurses-devel sqlite-devel \
    readline-devel tk-devel libffi-devel expat-devel gdbm-devel

# 2. 下载 Python 3.9 源码
cd /opt
wget https://www.python.org/ftp/python/3.9.0/Python-3.9.0.tar.xz
tar -xf Python-3.9.0.tar.xz
cd Python-3.9.0

# 3. 设置环境变量,使编译器和链接器能找到 OpenSSL 1.1.1
export CFLAGS="$CFLAGS $(pkg-config --cflags openssl11)"
export LDFLAGS="$LDFLAGS $(pkg-config --libs openssl11)"

# 4. 配置、编译、安装
./configure --enable-optimizations --prefix=/usr/local/python3.9
make -j$(nproc)
make altinstall

# 5. 创建符号链接(可选)
ln -s /usr/local/python3.9/bin/python3.9 /usr/local/bin/python3.9
ln -s /usr/local/python3.9/bin/pip3.9 /usr/local/bin/pip3.9

# 6. 验证 SSL 模块
/usr/local/python3.9/bin/python3.9 -c "import ssl; print(ssl.OPENSSL_VERSION)"

echo "Python 3.9 installation completed successfully."

5. 验证与测试

5.1 测试 SSL 导入

复制代码
  python3.9 -c "import ssl; print('SSL module is available')"

5.2 测试 pip 使用 HTTPS 源

复制代码
  pip3.9 install --upgrade pip

应不再出现 SSL 相关警告。

5.3 测试 Ansible 远程执行

在 Ansible 控制节点上,确保 inventory 中指定了解释器路径:

复制代码
  [target]
192.168.233.128 ansible_python_interpreter=/usr/local/python3.9/bin/python3.9

然后执行涉及 HTTPS 下载的任务,应不再报 SSL 验证错误。

6. 常见问题及注意事项

6.1 为什么不用 --with-openssl

在 Python 3.9 中,--with-openssl 只能指定一个根目录(如 /usr/local/openssl),要求该目录下有 include/lib/ 子目录。而通过 EPEL 安装的 openssl11-devel 将头文件放在了 /usr/include/openssl11,库文件在 /usr/lib64/openssl11,不符合标准结构。使用 pkg-config 传递标志是更灵活且通用的做法。

6.2 如果 pkg-config 找不到 openssl11

请确保 openssl11-devel 已正确安装,其生成的 .pc 文件通常位于 /usr/lib64/pkgconfig/openssl11.pc。如果 pkg-config 仍找不到,可以设置 PKG_CONFIG_PATH 环境变量:

复制代码
  export PKG_CONFIG_PATH=/usr/lib64/pkgconfig:$PKG_CONFIG_PATH

6.3 关于 zlib 模块缺失

如果同时遇到 zlib 模块缺失,请确保已安装 zlib-devel,并在编译前导出 CFLAGSLDFLAGS 中包含 zlib 的相关路径(通常系统默认路径已包含,无需额外指定)。

6.4 使用 altinstall 避免冲突

始终使用 make altinstall 而不是 make install,以防止覆盖系统自带的 Python 2 或 Python 3 可执行文件,避免破坏系统工具(如 yum)。

6.5 虚拟环境建议

即使编译成功,也建议为项目创建虚拟环境,避免使用 root 权限安装包,并隔离依赖。

结语

通过上述方法,可以在 CentOS 7 上成功编译出带有完整 SSL 支持的 Python 3.9,彻底解决 _ssl 模块缺失的问题。本文提供的脚本已在 CentOS 7.9 上验证通过,可放心使用。如果在实践中遇到其他问题,欢迎反馈交流。

相关推荐
lly2024061 分钟前
C 标准库 - `<stdio.h>`
开发语言
沫璃染墨3 分钟前
C++ string 从入门到精通:构造、迭代器、容量接口全解析
c语言·开发语言·c++
jwn9993 分钟前
Laravel6.x核心特性全解析
开发语言·php·laravel
迷藏4945 分钟前
**发散创新:基于Rust实现的开源合规权限管理框架设计与实践**在现代软件架构中,**权限控制(RBAC)** 已成为保障
java·开发语言·python·rust·开源
功德+n34 分钟前
Linux下安装与配置Docker完整详细步骤
linux·运维·服务器·开发语言·docker·centos
明日清晨36 分钟前
python扫码登录dy
开发语言·python
我是唐青枫42 分钟前
C#.NET gRPC 深入解析:Proto 定义、流式调用与服务间通信取舍
开发语言·c#·.net
JJay.1 小时前
Kotlin 高阶函数学习指南
android·开发语言·kotlin
bazhange1 小时前
python如何像matlab一样使用向量化替代for循环
开发语言·python·matlab
jinanwuhuaguo1 小时前
截止到4月8日,OpenClaw 2026年4月更新深度解读剖析:从“能力回归”到“信任内建”的范式跃迁
android·开发语言·人工智能·深度学习·kotlin