I'm experiencing some weird behavior with requests and certifi, and am not entirely sure if/how they're interacting with my system's CA bundle, and how they should be.
Locally (ubuntu 16.04), inside a virtualenv
When I run a simple request locally with requests==2.18.4 and certifi==2018.1.18, things go fine
$ pip freeze | grep "requests"
requests==2.18.4
requests-mock==0.6.0
requests-oauthlib==0.4.2
$ pip freeze | grep "certifi"
certifi==2018.1.18
$ openssl version
OpenSSL 1.0.2g 1 Mar 2016
$ python
Python 3.4.3 (default, Mar 7 2018, 11:51:27)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import requests
>>> requests.utils.DEFAULT_CA_BUNDLE_PATH
'/PATH/TO/APP/venv/lib/python3.4/site-packages/certifi/cacert.pem'
>>> requests.get('https://google.com')
<Response [200]>
>>>
However, on a different, remote server with the same libraries installed (with admittedly outdated certificates installed locally) my requests behavior is entirely different:
Remote server (centos 6.6)
$ pip freeze | grep "requests"
requests==2.18.4
requests-mock==0.6.0
requests-oauthlib==0.8.0
$ pip freeze | grep "certifi"
certifi==2018.1.18
$ openssl version
OpenSSL 1.0.1e-fips 11 Feb 2013
$ python
Python 3.4.3 (default, Apr 7 2015, 17:44:40)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-11)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import requests
>>> requests.utils.DEFAULT_CA_BUNDLE_PATH
'/PATH/TO/APP/venv/lib/python3.4/site-packages/certifi/cacert.pem'
>>> requests.get('https://google.com')
...
requests.exceptions.SSLError: HTTPSConnectionPool(host='google.com', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:600)'),))
The same error occurs when I run:
requests.get('https://google.com', verify=requests.utils.DEFAULT_CA_BUNDLE_PATH)
My (perhaps incorrect) assumption is that this is due to the remote system's outdated openssl library. If that's the case, this surprises me since I thought that requests was using the certifi CA cert bundle, which is the most recent version on both systems.
In other words, why does it matter (if it does matter) what version of OpenSSL I have installed on my system if I'm using the python certifi library. in python 3.4.3?
NOTE
1) Upgrading my system's cert database is a bit challenging due to the way my org handles package management, and I was under the impression that our use of the certifi library made this unnecessary anyway.
2) I know that I can disable SSL verification, or maybe even call requests.get with a path to a valid cert file via verify=___. However, I don't have this control in third-party libraries that I use locally, which encounter the same error. I'd prefer to get a vanilla requests.get("https://google.com") command running without added parameters.