python请求网页提示:ssl.SSLCertVerificationError...Unable to get local issuer certificate

openssl s_client -connect www.baidu.com:443 -4<<< "Q"

提示:Verify return code: 20 (unable to get local issuer certificate)

此错误是OPENSSLDIR目录不包含证书导致的,这可能是由某些升级/重新安装引起的。

全新编译安装的opensll没有root CA certificates,见:https://www.openssl.org/docs/faq.html#USER15

大意如下(机翻):

OpenSSL软件没有任何根CA证书,因为OpenSSL项目没有包含或排除任何特定CA的任何政策,也不打算设置此类政策。决定支持哪些CA取决于应用程序开发人员或管理员。其他项目也有其他策略,因此您可以提取Mozilla和/或modssl使用的CA捆绑包。

解决OPENSSLDIR目录不包含证书的办法:

方法一、

1、查看OPENSSLDIR路径:

openssl version -d
# 输出:OPENSSLDIR: "/usr/local/openssl/ssl"

2、下载curl网站提供的证书保存到OPENSSLDIR目录

wget -nv https://curl.se/ca/cacert.pem -O /usr/local/openssl/ssl/cert.pem --no-check-certificate

相关:https://curl.se/docs/caextract.html

方法二、

重新编译安装openssl,使用发行商的OpenSSL配置和系统信任存储库

openssl编译安装:http://www.gmloc.me/101.html

python文档:在类Unix环境下使用Python:自定义OpenSSL

方法三、

1、查看默认配置路劲:

find /etc/ -name openssl.cnf -printf "%h\n"
# 输出:/etc/pki/tls

2、查看OPENSSLDIR路径:

openssl version -d
# 输出:OPENSSLDIR: "/usr/local/openssl/ssl"

3、设置软连接

ln -s /etc/pki/tls/cert.pem /usr/local/openssl/ssl/cert.pem

实际上/etc/pki/tls/cert.pem也是软连接,源地址是:/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem。

所以这样也行。

ln -s /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem /usr/local/openssl/ssl/cert.pem

方法四、

...