Python 3.11 pip 无 SSL 模块问题:使用 OpenSSL 3.0.13 重新编译 Python
注意:以下操作最好在测试机试验一遍
一、问题原因分析(为什么 pip 会缺 SSL?)
Python 的 ssl 模块并不是纯 Python 实现,而是:
-
编译时依赖系统中的 OpenSSL
-
如果在
./configure阶段:- 找不到
openssl/ssl.h - 或 OpenSSL 版本不兼容
- 找不到
-
那么:
_ssl.so不会被编译import ssl会失败- pip 无法访问 HTTPS
📌 Python 3.11 推荐使用 OpenSSL ≥ 1.1.1(3.0.x 完全支持)
三、解决思路总览
我们的解决方案分为 5 步:
- 安装并准备 OpenSSL 3.0.13
- 清理 Python 旧的编译残留
- 使用
--with-openssl明确指定 OpenSSL 路径 - 验证
_ssl模块是否成功生成 - 验证
ssl/pip是否可用
四、完整自动化编译脚本(推荐)
⚠️ 假设:
- OpenSSL 安装在:
/usr/local/openssl-3.0.13- Python 源码在:
/usr/local/src/Python-3.11.9
🔧 一键编译脚本
bash
#!/bin/bash
set -e
echo "=== 开始重新编译 Python 3.11.9 with OpenSSL 3.0.13 ==="
cd /usr/local/src/Python-3.11.9
# 清理
echo "清理之前的编译..."
sudo make distclean 2>/dev/null || true
# 设置环境变量
export OPENSSL_DIR="/usr/local/openssl-3.0.13"
export LDFLAGS="-L${OPENSSL_DIR}/lib64"
export CPPFLAGS="-I${OPENSSL_DIR}/include"
export LD_LIBRARY_PATH="${OPENSSL_DIR}/lib64:$LD_LIBRARY_PATH"
export PKG_CONFIG_PATH="${OPENSSL_DIR}/lib64/pkgconfig"
echo "配置 Python..."
sudo -E ./configure \
--prefix=/usr/local/python3.11.9 \
--with-openssl=${OPENSSL_DIR} \
--with-openssl-rpath=auto \
--enable-shared \
--enable-loadable-sqlite-extensions \
LDFLAGS="-Wl,-rpath=/usr/local/python3.11.9/lib -L${OPENSSL_DIR}/lib64" \
CPPFLAGS="-I${OPENSSL_DIR}/include"
# 检查配置结果
echo ""
echo "=== 检查 OpenSSL 配置 ==="
if grep -q "checking for openssl/ssl.h in ${OPENSSL_DIR}... yes" config.log && \
grep -q "checking whether compiling and linking against OpenSSL works... yes" config.log; then
echo "✓ OpenSSL 配置成功"
else
echo "✗ OpenSSL 配置失败,请检查 config.log"
grep -A 5 "checking for openssl" config.log | tail -20
exit 1
fi
echo ""
echo "开始编译(这可能需要几分钟)..."
sudo -E make -j$(nproc)
echo ""
echo "检查 _ssl 模块是否生成..."
SSL_MODULE=$(find . -name "_ssl*.so" | head -1)
if [ -n "$SSL_MODULE" ]; then
echo "✓ 找到 SSL 模块: $SSL_MODULE"
else
echo "✗ 未找到 SSL 模块"
exit 1
fi
echo ""
echo "安装 Python..."
sudo make install
echo ""
echo "配置系统库和环境..."
echo "/usr/local/python3.11.9/lib" | sudo tee /etc/ld.so.conf.d/python3.11.conf
sudo ldconfig
echo 'export PATH=/usr/local/python3.11.9/bin:$PATH' | sudo tee /etc/profile.d/python3.11.sh
source /etc/profile.d/python3.11.sh
echo ""
echo "=== 验证安装 ==="
echo "Python 版本:"
/usr/local/python3.11.9/bin/python3.11 --version
echo ""
echo "OpenSSL 版本:"
/usr/local/python3.11.9/bin/python3.11 -c "import ssl; print(ssl.OPENSSL_VERSION)"
echo ""
echo "测试 pip:"
/usr/local/python3.11.9/bin/pip3.11 --version
echo ""
echo "=== 安装完成 ==="
五、关键参数详解(非常重要)
1️⃣ --with-openssl
bash
--with-openssl=/usr/local/openssl-3.0.13
👉 明确告诉 Python:用哪个 OpenSSL 编译
2️⃣ --with-openssl-rpath=auto
bash
--with-openssl-rpath=auto
👉 避免运行时找不到 libssl.so
👉 比手动改 LD_LIBRARY_PATH 更稳定
3️⃣ --enable-shared
bash
--enable-shared
👉 生成 libpython3.11.so
👉 对 embedding、某些 C 扩展很有用
六、如何确认 SSL 模块真的生效?
✅ 1. 查看 _ssl 模块
bash
find /usr/local/python3.11.9 -name "_ssl*.so"
有输出即成功。
✅ 2. Python 内部验证
bash
python3.11 -c "import ssl; print(ssl.OPENSSL_VERSION)"
示例输出:
text
OpenSSL 3.0.13 30 Jan 2024
✅ 3. pip 验证
bash
pip3.11 install requests
无 HTTPS 报错即可 🎉
七、常见错误排查
❌ configure 阶段找不到 OpenSSL
text
checking for openssl/ssl.h... no
解决:
- 确认 OpenSSL 是 源码安装
- 确认
${OPENSSL_DIR}/include/openssl/ssl.h存在
❌ 运行时报 libssl 找不到
text
error while loading shared libraries: libssl.so.3
解决:
bash
ldd $(which python3.11)
ldconfig
或检查 --with-openssl-rpath
八、总结
✅ 本文通过 显式指定 OpenSSL 3.0.13
✅ 从编译阶段解决 Python 缺失 SSL 模块的问题
✅ 适用于:
- pip 无法使用
- requests / urllib3 报 SSL 错
- Python 3.11 源码安装环境
一句话总结:
pip 没 SSL,不是 pip 的问题,是 Python 编译时 OpenSSL 没配好。