Installed certifi, set REQUESTS_CA_BUNDLE env var, still getting SSL error.

I am using the jenkinsapi module which uses requests under the hood. If I try to use it out of the box, pointing it at a jenkins server that uses SSL, I get:

SSLError: [Errno 1] _ssl.c:504: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

jenkinsapi doesn't provide a hook to set verify=False. I tried saving the certificate from the jenkins server and setting the REQUESTS_CA_BUNDLE environment variable to point to it, and still got the same error. I also tried installing certifi but it makes no difference.

I know I could hack the jenkinsapi code but that is not satisfactory because all users of my code would have to do the same thing. Am I overlooking something?


Can you show me what the saved certificate looked like please? Should be possible to simply paste it in here.


Thanks for responding. I re-saved the certificate and things are working now.


Damn! I spoke too soon. Here is the cert:

-----BEGIN CERTIFICATE-----
MIIGQDCCBSigAwIBAgIKWQnHpQAAAAAIzjANBgkqhkiG9w0BAQUFADBZMRMwEQYK
CZImiZPyLGQBGRYDY29tMRQwEgYKCZImiZPyLGQBGRYEZWJheTEUMBIGCgmSJomT
8ixkARkWBGNvcnAxFjAUBgNVBAMTDUFNRVItU1NMQ0EtMDIwHhcNMTIxMTE4MDUz
MTA4WhcNMTQxMTE4MDUzMTA4WjB1MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2Fs
aWZvcm5pYTERMA8GA1UEBxMIU2FuIEpvc2UxFDASBgNVBAoTC1BheVBhbCBJbmMu
MQwwCgYDVQQLEwNDRUkxGjAYBgNVBAMTEWZ1c2lvbi5wYXlwYWwuY29tMIIBIjAN
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwOZj4ezQ/k5vTU6E63uNsP+LZjeg
4kTEUwSzFsRj3NImQdfOrQ7W7S386ep2EZZqmjevO6HBzkaXaYYQ0GSqthdspd53
A8GnLi0q43oFy+kyAc2ItAM0SH/GOt0J+5EUdS12S821WMiwebHInSHINAjexAHN
Sm87yXCyO8mZ3Jzc3+PFraveF9WFmE0NLZUDpEMxq17K3/6iGLsVO/YZkUpaAXNJ
962fGrIZ4xcvK//S903ehloKwQnRCgtNoGCmvsoDftbYye6LfRh/rH3xWFXIUmWG
Wib27ZwAgbyxz2FPcexie4FB/IzbH2l9Tp5rzGWfs1159VmVhQ/L3EJIDQIDAQAB
o4IC7DCCAugwHQYDVR0OBBYEFMkZJD5QaahE21k37UvPIP1VmZ1SMB8GA1UdIwQY
MBaAFLI24M3s4ViBTJbTf1lWAEsUzehVMIIBDQYDVR0fBIIBBDCCAQAwgf2ggfqg
gfeGgb9sZGFwOi8vL0NOPUFNRVItU1NMQ0EtMDIsQ049QU1FUi1TU0xDQS0wMixD
Tj1DRFAsQ049UHVibGljJTIwS2V5JTIwU2VydmljZXMsQ049U2VydmljZXMsQ049
Q29uZmlndXJhdGlvbixEQz1jb3JwLERDPWViYXksREM9Y29tP2NlcnRpZmljYXRl
UmV2b2NhdGlvbkxpc3Q/YmFzZT9vYmplY3RDbGFzcz1jUkxEaXN0cmlidXRpb25Q
b2ludIYzaHR0cDovL3BraS5jb3JwLmViYXkuY29tL0NlcnREYXRhL0FNRVItU1NM
Q0EtMDIuY3JsMIIBTgYIKwYBBQUHAQEEggFAMIIBPDCBsQYIKwYBBQUHMAKGgaRs
ZGFwOi8vL0NOPUFNRVItU1NMQ0EtMDIsQ049QUlBLENOPVB1YmxpYyUyMEtleSUy
MFNlcnZpY2VzLENOPVNlcnZpY2VzLENOPUNvbmZpZ3VyYXRpb24sREM9Y29ycCxE
Qz1lYmF5LERDPWNvbT9jQUNlcnRpZmljYXRlP2Jhc2U/b2JqZWN0Q2xhc3M9Y2Vy
dGlmaWNhdGlvbkF1dGhvcml0eTBbBggrBgEFBQcwAoZPaHR0cDovL3BraS5jb3Jw
LmViYXkuY29tL0NlcnREYXRhL0FNRVItU1NMQ0EtMDIuY29ycC5lYmF5LmNvbV9B
TUVSLVNTTENBLTAyLmNydDApBggrBgEFBQcwAYYdaHR0cDovL3BraS5jb3JwLmVi
YXkuY29tL29jc3AwIQYJKwYBBAGCNxQCBBQeEgBXAGUAYgBTAGUAcgB2AGUAcjAL
BgNVHQ8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQEFBQAD
ggEBAFj5s9SdtRpXLz03BjPFsDvQPzoyML9ngHL5zyYMlotUpD7d+aO41Q2E2+LO
REfbd3NAnLT3MfWMHAxNaZ4TRUog1fFJmLJxHTBax5fpmY8YAhiPjQIO+IZOUZO3
4lAwXKsq4ylWS2tlbxL56mPngN2EzLisWgIZqJSx9zd1K/LvKyvs/R3wxBerhTN5
LyHFf9/ByUhaqgIE8jydM4qiS8o3zxjrPAIbi6lnZjktkguYTSAKDoHb17BkNoPr
mU1xDtD1/FuX22dfHpqmJSYVubPVfUTvGB3julT2GNNREoHsQI7wmgFBEMaTdvJq
42DUnHIK0pdMzb2urxL/toZ3mHY=
-----END CERTIFICATE-----

Traceback (most recent call last):
  File "goals.py", line 3, in <module>
    J = api.Jenkins('https://fusion.[REDACTED].com/jenkins/')
  File "C:\python27\lib\site-packages\jenkinsapi\jenkins.py", line 35, in **init**
    JenkinsBase.**init**(self, baseurl)
  File "C:\python27\lib\site-packages\jenkinsapi\jenkinsbase.py", line 27, in **init**
    self.poll()
  File "C:\python27\lib\site-packages\jenkinsapi\jenkinsbase.py", line 49, in poll
    self._data = self._poll()
  File "C:\python27\lib\site-packages\jenkinsapi\jenkinsbase.py", line 53, in _poll
    return self.get_data(url)
  File "C:\python27\lib\site-packages\jenkinsapi\jenkinsbase.py", line 57, in get_data
    response = requester.get_url(url)
  File "C:\python27\lib\site-packages\jenkinsapi\utils\requester.py", line 59, in get_url
    return requests.get(url, *_requestKwargs)
  File "C:\python27\lib\site-packages\requests\api.py", line 55, in get
    return request('get', url, *_kwargs)
  File "C:\python27\lib\site-packages\requests\api.py", line 44, in request
    return session.request(method=method, url=url, *_kwargs)
  File "C:\python27\lib\site-packages\requests\sessions.py", line 335, in request
    resp = self.send(prep, *_send_kwargs)
  File "C:\python27\lib\site-packages\requests\sessions.py", line 438, in send
    r = adapter.send(request, **kwargs)
  File "C:\python27\lib\site-packages\requests\adapters.py", line 331, in send
    raise SSLError(e)
requests.exceptions.SSLError: [Errno 1] _ssl.c:504: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed


Could you try to connect using requests directly, without going through jenkinsapi but while passing the certificate you safes to requests.


r=requests.get(url,verify=certfile)

SSLError: [Errno 1] _ssl.c:504: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

r=requests.get(url,cert=certfile)

SSLError: [Errno 336265225] _ssl.c:351: error:140B0009:SSL routines:SSL_CTX_use_PrivateKey_file:PEM lib

Does that mean I'm supposed to have the private key? I doubt the server owners will let me have it.


Sorry, ignore the second part - I figured out specifying "cert" is about authenticating yourself to the server which is not the issue here.


Now we know the problem lies with the cert :-)
Given the cert is from the CA and not the server itself: Is the chain of thrust complete?
You should see this chain in your browser where you exported the cert.
To verifiy a certificate requests needs a complete chain. The last element is sent by the server, I assume you only saved the root certificate to a file.
You still need all the certificates between the root and the leaf. Those can either be sent by the server alongside the leaf cert, or you should be able to add them to the certificate file.


Thanks - I finally got it working! To summarize, in case this is helpful to someone else: I needed to export every cert in the chain from the server itself to the root, saving each one in base64 format, then copy all the certs into a single file, and set the environment variable REQUESTS_CA_BUNDLE to point to it.

Thanks again for your help!


For other Googlers - you can disable SSL verification in jenkinsapi using:

``` python
from jenkinsapi.jenkins import Jenkins
from jenkinsapi.utils.requester import Requester

j = Jenkins(base_url, requester=Requester(username, password, baseurl=base_url, ssl_verify=False))
```


I encountered the same issue and ssl certifacate verify failed issue, by review boto3 code, I found the REQUESTS_CA_BUNDLE is not set, so I fixed the both issue by setting it manually:

```
from boto3.session import Session
import os

# debian
os.environ['REQUESTS_CA_BUNDLE'] = os.path.join(
    '/etc/ssl/certs/',
    'ca-certificates.crt')
# centos
#   'ca-bundle.crt')
```

For aws-cli, I guess setting REQUESTS_CA_BUNDLE in ~/.bashrc will fix this issue (not tested because my aws-cli works without it)

```
REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt # ca-bundle.crt
export REQUESTS_CA_BUNDLE
```