CentOS 7 编译安装 Python 3.10 并解决 SSL 问题
- [CentOS 7 编译安装 Python 3.10 并解决 SSL 问题](#CentOS 7 编译安装 Python 3.10 并解决 SSL 问题)
-
- 一、问题现象
- 二、完整解决步骤
-
- 第一步:安装依赖
- [第二步:编译安装 OpenSSL 1.1.1](#第二步:编译安装 OpenSSL 1.1.1)
- [第三步:编译安装 Python 3.10](#第三步:编译安装 Python 3.10)
- 第四步:配置环境变量
- 第五步:验证安装
- 第六步:创建虚拟环境
- 三、常见问题
-
- [Q1: 为什么必须用 OpenSSL 1.1.1?](#Q1: 为什么必须用 OpenSSL 1.1.1?)
- [Q2: 如何卸载已编译的 Python?](#Q2: 如何卸载已编译的 Python?)
- [Q3: 其他替代方案](#Q3: 其他替代方案)
-
- [方案一:用 Software Collections 版本的 Python 3.9 代替。](#方案一:用 Software Collections 版本的 Python 3.9 代替。)
- [方案二:使用pyenv预编译的 Python。](#方案二:使用pyenv预编译的 Python。)
- [方案 三:使用 miniconda(绕过系统 Python)](#方案 三:使用 miniconda(绕过系统 Python))
CentOS 7 编译安装 Python 3.10 并解决 SSL 问题
一、问题现象
报错复现
CentOS7 自带的是Python3.6。想通过源码编译升级到Python3.10以上。在编译安装后,使用pip时,出现以下报错。
bash
WARNING: pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.
Could not fetch URL https://mirrors.aliyun.com/pypi/simple/pip/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='mirrors.aliyun.com', port=443): Max retries exceeded with url: /pypi/simple/pip/ (Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available.")) - skipping
pip无法连接 HTTPS 源,报错Can't connect to HTTPS URL because the SSL module is not availableimport ssl失败,报错ModuleNotFoundError: No module named '_ssl'- 系统已安装
openssl-devel,但 Python 编译时仍无法启用 SSL 支持
根本原因
- CentOS 7 默认 OpenSSL 版本太旧(1.0.2k),Python 3.10+ 需要 OpenSSL 1.1.1+
- Python 编译时找不到 OpenSSL 头文件和库文件(pkg-config 配置问题)
- SSL 模块编译成功后,Python 找不到 CA 证书导致 HTTPS 验证失败
这个重新编译的比较费劲,不想麻烦的建议滑到到最底下的其他解决方案。卸载已经编译的Python,然后用其他工具来安装Python。
二、完整解决步骤
按照该教程编辑安装后,Python3命令调用的是Python3.10。原来系统的Python3.6仍保留着,可以通过Python3.6命令来调用。
第一步:安装依赖
bash
sudo yum groupinstall "Development Tools"
sudo yum install -y openssl-devel libffi-devel bzip2-devel zlib-devel \
readline-devel sqlite-devel ncurses-devel gdbm-devel xz-devel \
tk-devel uuid-devel libuuid-devel pkgconfig
第二步:编译安装 OpenSSL 1.1.1
bash
cd /usr/local/src
sudo wget https://www.openssl.org/source/openssl-1.1.1w.tar.gz
sudo tar xzf openssl-1.1.1w.tar.gz
cd openssl-1.1.1w
# 安装到独立目录,不覆盖系统版本
sudo ./config --prefix=/usr/local/openssl-1.1.1 shared zlib
sudo make -j$(nproc)
sudo make install
# 配置动态链接库
echo "/usr/local/openssl-1.1.1/lib" | sudo tee /etc/ld.so.conf.d/openssl-1.1.1.conf
sudo ldconfig
# 验证
/usr/local/openssl-1.1.1/bin/openssl version
# 输出:OpenSSL 1.1.1w 11 Sep 2023
第三步:编译安装 Python 3.10
bash
cd /usr/local/src
sudo wget https://www.python.org/ftp/python/3.10.20/Python-3.10.20.tgz
sudo tar xzf Python-3.10.20.tgz
cd Python-3.10.20
# 清理(如果是重新编译)
sudo make clean
sudo rm -rf build/
# 配置环境变量(关键!)
export PKG_CONFIG_PATH=/usr/local/openssl-1.1.1/lib/pkgconfig:$PKG_CONFIG_PATH
export LDFLAGS="-L/usr/local/openssl-1.1.1/lib -Wl,-rpath,/usr/local/openssl-1.1.1/lib"
export CPPFLAGS="-I/usr/local/openssl-1.1.1/include"
export LD_LIBRARY_PATH=/usr/local/openssl-1.1.1/lib:$LD_LIBRARY_PATH
# 配置(使用 sudo -E 保留环境变量)
sudo -E ./configure --enable-optimizations \
--with-openssl=/usr/local/openssl-1.1.1 \
--with-openssl-rpath=/usr/local/openssl-1.1.1/lib
# 检查 SSL 检测是否通过
./configure 2>&1 | grep -E "(ssl|SSL|openssl)"
# 预期输出:
# checking whether compiling and linking against OpenSSL works... yes
# checking whether OpenSSL provides required APIs... yes ← 关键!
# 编译安装
sudo make -j$(nproc)
sudo make altinstall
第四步:配置环境变量
bash
# 添加到 ~/.bashrc
echo 'export PATH=/usr/local/bin:$PATH' >> ~/.bashrc
echo 'export SSL_CERT_FILE=/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem' >> ~/.bashrc
echo 'export REQUESTS_CA_BUNDLE=/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem' >> ~/.bashrc
source ~/.bashrc
第五步:验证安装
bash
# 检查版本
python3.10 --version
# 检查 SSL 模块
python3.10 -c "import ssl; print(ssl.OPENSSL_VERSION)"
# 输出:OpenSSL 1.1.1w
# 检查 _ssl 模块
python3.10 -c "import _ssl; print(_ssl.__file__)"
# 测试 HTTPS 访问
python3.10 -c "import urllib.request; print(urllib.request.urlopen('https://www.baidu.com').status)"
# 输出:200
# 检查 pip
pip3.10 --version
第六步:创建虚拟环境
bash
# 创建虚拟环境
python3.10 -m venv ~/myenv
# 激活
source ~/myenv/bin/activate
# 升级 pip
pip install --upgrade pip
# 安装 certifi(确保 CA 证书最新)
pip install certifi
三、常见问题
Q1: 为什么必须用 OpenSSL 1.1.1?
Python 3.10+ 依赖 OpenSSL 1.1.1 提供的新 API,CentOS 7 默认的 1.0.2k 版本太旧,会导致 checking whether OpenSSL provides required APIs... no。
Q2: 如何卸载已编译的 Python?
bash
cd /usr/local/src/Python-3.10.20
sudo make uninstall
# 或手动删除
sudo rm -rf /usr/local/bin/python3.10* /usr/local/bin/pip3.10* \
/usr/local/lib/python3.10 /usr/local/include/python3.10 \
/usr/local/lib/libpython3.10*
Q3: 其他替代方案
方案一:用 Software Collections 版本的 Python 3.9 代替。
SCL 版本已解决 SSL 兼容问题,无需自行编译。
bash
# 1. 安装 SCL 仓库
sudo yum install centos-release-scl
# 2. 安装 Python 3.9(或 3.8/3.11)
sudo yum install rh-python39
# 3. 启用并使用
scl enable rh-python39 bash
#永久启用 SCL Python(不用每次执行 scl enable)
echo 'source /opt/rh/rh-python39/enable' >> ~/.bashrc
方案二:使用pyenv预编译的 Python。
如果编译问题持续,考虑用 pyenv 自动处理这些依赖
bash
# 安装 pyenv
curl https://pyenv.run | bash
exec $SHELL
# 安装 Python 3.10(pyenv 会自动处理 OpenSSL)
CFLAGS="-I/usr/local/openssl-1.1.1/include" \
LDFLAGS="-L/usr/local/openssl-1.1.1/lib" \
pyenv install 3.10.13
# 使用
pyenv global 3.10.13
方案 三:使用 miniconda(绕过系统 Python)
bash
# 下载并安装 miniconda
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
bash Miniconda3-latest-Linux-x86_64.sh
# 创建 conda 环境(自带 SSL 支持)
conda create -n myenv python=3.9
conda activate myenv