python 2.7.5请求和证书验证失败

时间:2015-05-14 15:29:03

标签: python ssl curl puppet-enterprise

我无法使用python的请求包向GET请求提交 Puppet 3.7的REST API。我在这里查看了这个文档:

http://docs.python-requests.org/en/latest/user/advanced/#ssl-cert-verification

但我仍然遇到麻烦。这是我的剧本:

[root@ppt-001 RESTClients]# cat add-group.py
#!/usr/bin/env python

import requests

# curl https://ppt-001.example.com:4433/classifier-api/v1/groups \
# -H "Content-Type: application/json" \
# --cert /etc/puppetlabs/puppet/ssl/certs/ppt-001.example.com.pem \
# --key /etc/puppetlabs/puppet/ssl/private_keys/ppt-001.example.com.pem \
# --cacert /etc/puppetlabs/puppet/ssl/certs/ca.pem | python -m json.tool

url='https://ppt-001.example.com:4433/classifier-api/v1/groups'
headers = {"Content-Type": "application/json"}
data={}
cacert='/etc/puppetlabs/puppet/ssl/certs/ca.pem'
key='/etc/puppetlabs/puppet/ssl/private_keys/ppt-001.example.com.pem'
cert='/etc/puppetlabs/puppet/ssl/certs/ppt-001.example.com.pem'
result = requests.get(url,
        data=data, #no data needed for this request
        headers=headers, #dict {"Content-Type":"application/json"}
        cert=(cacert,key), #key/cert pair 
        verify=cert
        )
print result.json()

我正在使用这个版本的python:

[root@ppt-001 RESTClients]# python -V
Python 2.7.5

以下是我执行脚本时会发生的事情:

[root@ppt-001 RESTClients]# ./add-group.py
/usr/lib/python2.7/site-packages/requests-2.7.0-py2.7.egg/requests/packages/urllib3/util/ssl_.py:90: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
  InsecurePlatformWarning
Traceback (most recent call last):
  File "./add-group.py", line 21, in <module>
    verify=cert
  File "/usr/lib/python2.7/site-packages/requests-2.7.0-py2.7.egg/requests/api.py", line 69, in get
    return request('get', url, params=params, **kwargs)
  File "/usr/lib/python2.7/site-packages/requests-2.7.0-py2.7.egg/requests/api.py", line 50, in request
    response = session.request(method=method, url=url, **kwargs)
  File "/usr/lib/python2.7/site-packages/requests-2.7.0-py2.7.egg/requests/sessions.py", line 465, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/lib/python2.7/site-packages/requests-2.7.0-py2.7.egg/requests/sessions.py", line 573, in send
    r = adapter.send(request, **kwargs)
  File "/usr/lib/python2.7/site-packages/requests-2.7.0-py2.7.egg/requests/adapters.py", line 431, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: [Errno 1] _ssl.c:504: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
[root@ppt-001 RESTClients]# 

我怀疑requests不喜欢Puppet使用的自签名证书,但是如果我发出这个curl命令...

curl https://ppt-001.example.com:4433/classifier-api/v1/groups \
-H "Content-Type: application/json" \
--cert /etc/puppetlabs/puppet/ssl/certs/ppt-001.example.com.pem \
--key /etc/puppetlabs/puppet/ssl/private_keys/ppt-001.example.com.pem \
--cacert /etc/puppetlabs/puppet/ssl/certs/ca.pem | python -m json.tool

......一切正常。

更新:

我已安装requests[security]

    [root@ppt-001 RESTClients]# pip install requests[security]
    Requirement already satisfied (use --upgrade to upgrade): requests[security] in /usr/lib/python2.7/site-packages/requests-2.7.0-py2.7.egg
      Installing extra requirements: 'security'
    Requirement already satisfied (use --upgrade to upgrade): pyOpenSSL in /usr/lib64/python2.7/site-packages (from requests[security])
    Downloading/unpacking ndg-httpsclient (from requests[security])
      Downloading ndg_httpsclient-0.4.0.tar.gz
      Running setup.py egg_info for package ndg-httpsclient

    Downloading/unpacking pyasn1 (from requests[security])
      Downloading pyasn1-0.1.7.tar.gz (68kB): 68kB downloaded
      Running setup.py egg_info for package pyasn1

    Installing collected packages: ndg-httpsclient, pyasn1
      Running setup.py install for ndg-httpsclient
        Skipping installation of /usr/lib/python2.7/site-packages/ndg/__init__.py (namespace package)

        Installing /usr/lib/python2.7/site-packages/ndg_httpsclient-0.4.0-py2.7-nspkg.pth
        Installing ndg_httpclient script to /usr/bin
      Running setup.py install for pyasn1

    Successfully installed ndg-httpsclient pyasn1
    Cleaning up...

但是现在我在运行脚本时得到了这个putput:

    [root@ppt-001 RESTClients]# ./add-group.py
    Traceback (most recent call last):
      File "./add-group.py", line 25, in <module>
        verify=cert
      File "/usr/lib/python2.7/site-packages/requests-2.7.0-py2.7.egg/requests/api.py", line 69, in get
        return request('get', url, params=params, **kwargs)
      File "/usr/lib/python2.7/site-packages/requests-2.7.0-py2.7.egg/requests/api.py", line 50, in request
        response = session.request(method=method, url=url, **kwargs)
      File "/usr/lib/python2.7/site-packages/requests-2.7.0-py2.7.egg/requests/sessions.py", line 465, in request
        resp = self.send(prep, **send_kwargs)
      File "/usr/lib/python2.7/site-packages/requests-2.7.0-py2.7.egg/requests/sessions.py", line 573, in send
        r = adapter.send(request, **kwargs)
      File "/usr/lib/python2.7/site-packages/requests-2.7.0-py2.7.egg/requests/adapters.py", line 370, in send
        timeout=timeout
      File "/usr/lib/python2.7/site-packages/requests-2.7.0-py2.7.egg/requests/packages/urllib3/connectionpool.py", line 544, in urlopen
        body=body, headers=headers)
      File "/usr/lib/python2.7/site-packages/requests-2.7.0-py2.7.egg/requests/packages/urllib3/connectionpool.py", line 341, in _make_request
        self._validate_conn(conn)
      File "/usr/lib/python2.7/site-packages/requests-2.7.0-py2.7.egg/requests/packages/urllib3/connectionpool.py", line 761, in _validate_conn
        conn.connect()
      File "/usr/lib/python2.7/site-packages/requests-2.7.0-py2.7.egg/requests/packages/urllib3/connection.py", line 238, in connect
        ssl_version=resolved_ssl_version)
      File "/usr/lib/python2.7/site-packages/requests-2.7.0-py2.7.egg/requests/packages/urllib3/contrib/pyopenssl.py", line 260, in ssl_wrap_socket
        ctx.use_privatekey_file(keyfile)
    OpenSSL.SSL.Error: [('x509 certificate routines', 'X509_check_private_key', 'key values mismatch')]

1 个答案:

答案 0 :(得分:3)

    cert=(cacert,key), #key/cert pair 
    verify=cert
....
OpenSSL.SSL.Error: [('x509 certificate routines', 'X509_check_private_key', 'key values mismatch')]

我认为您需要使用(cert,key)作为证书,并使用cacert进行验证:

    cert=(cert,key), #key/cert pair 
    verify=cacert