问题背景
在使用botocore库的make_request方法进行AWS服务调用时,许多开发者会遇到类似"SSL: CERTIFICATE_VERIFY_FAILED"的错误。这个问题通常发生在以下场景:
- 开发环境使用自签名证书
- 企业网络使用中间人(MITM)代理
- Python环境缺少根证书包
- AWS服务端点证书链不完整
错误现象
典型的错误堆栈如下:
botocore.exceptions.SSLError: SSL validation failed for [https://example.com] [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:997)
根本原因
该错误源于Python的ssl模块对服务器证书的严格验证机制。当出现以下情况时会导致验证失败:
- 服务器证书过期或被吊销
- 客户端系统时间不正确
- 证书链中缺少中间CA证书
- 主机名与证书SAN不匹配
- 系统根证书存储不完整
解决方案
方案1:临时禁用验证(不推荐生产环境)
通过配置botocore客户端参数禁用SSL验证:
import boto3
from botocore.config import Config
config = Config(
connect_timeout=10,
read_timeout=30,
retries={'max_attempts': 3},
verify=False # 禁用SSL验证
)
client = boto3.client('s3', config=config)
方案2:指定自定义CA证书包
将企业CA证书添加到验证链中:
import os os.environ['REQUESTS_CA_BUNDLE'] = '/path/to/custom/ca-bundle.crt'
方案3:更新系统证书存储
对于Python 3.10+,可使用系统证书存储:
import certifi import os os.environ['SSL_CERT_FILE'] = certifi.where()
方案4:修复证书链问题
使用OpenSSL检查证书链:
openssl s_client -connect example.com:443 -showcerts
最佳实践
生产环境中建议:
- 保持SSL验证开启状态
- 定期更新CA证书包
- 使用AWS Certificate Manager管理证书
- 配置适当的重试策略
底层原理
botocore的make_request最终使用urllib3的HTTPS连接池,其验证流程包括:
- TCP三次握手建立连接
- TLS/SSL握手协商
- 证书有效性验证(包括过期检查、签名验证等)
- 主机名验证
- OCSP状态检查(可选)