Set verify_certs default to True

If certifi is installed use it as default for ca_certs value
Closes #403
This commit is contained in:
Honza Král
2016-10-17 14:16:56 +02:00
parent aa3a7431ff
commit 8314f7b25c
5 changed files with 28 additions and 16 deletions
+2
View File
@@ -8,6 +8,8 @@ Changelog
Version compatible with elasticsearch 5.0 Version compatible with elasticsearch 5.0
* when using SSL certificate validation is now on by default. Install
``certifi`` or supply root certificate bundle.
* added ``headers`` arg to connections to support custom http headers * added ``headers`` arg to connections to support custom http headers
* passing in a keyword parameter with ``None`` as value will cause that param * passing in a keyword parameter with ``None`` as value will cause that param
to be ignored to be ignored
+6 -8
View File
@@ -189,9 +189,7 @@ elasticsearch cluster, including certificate verification and http auth::
['localhost', 'otherhost'], ['localhost', 'otherhost'],
http_auth=('user', 'secret'), http_auth=('user', 'secret'),
port=443, port=443,
use_ssl=True, use_ssl=True
verify_certs=True,
ca_certs=certifi.where(),
) )
# SSL client authentication using client_cert and client_key # SSL client authentication using client_cert and client_key
@@ -201,7 +199,6 @@ elasticsearch cluster, including certificate verification and http auth::
http_auth=('user', 'secret'), http_auth=('user', 'secret'),
port=443, port=443,
use_ssl=True, use_ssl=True,
verify_certs=True,
ca_certs='/path/to/cacert.pem', ca_certs='/path/to/cacert.pem',
client_cert='/path/to/client_cert.pem', client_cert='/path/to/client_cert.pem',
client_key='/path/to/client_key.pem', client_key='/path/to/client_key.pem',
@@ -209,10 +206,11 @@ elasticsearch cluster, including certificate verification and http auth::
.. warning:: .. warning::
By default SSL certificates won't be verified, pass in ``elasticsearch-py`` doesn't ship with default set of root certificates. To
``verify_certs=True`` to make sure your certificates will get verified. The have working SSL certificate validation you need to either specify your own
client doesn't ship with any CA certificates; easiest way to obtain the as ``ca_certs`` or install `certifi`_ which will be picked up
common set is by using the `certifi`_ package (as shown above). automatically.
See class :class:`~elasticsearch.Urllib3HttpConnection` for detailed See class :class:`~elasticsearch.Urllib3HttpConnection` for detailed
description of the options. description of the options.
+1 -1
View File
@@ -27,7 +27,7 @@ class RequestsHttpConnection(Connection):
:arg headers: any custom http headers to be add to requests :arg headers: any custom http headers to be add to requests
""" """
def __init__(self, host='localhost', port=9200, http_auth=None, def __init__(self, host='localhost', port=9200, http_auth=None,
use_ssl=False, verify_certs=False, ca_certs=None, client_cert=None, use_ssl=False, verify_certs=True, ca_certs=None, client_cert=None,
client_key=None, headers=None, **kwargs): client_key=None, headers=None, **kwargs):
if not REQUESTS_AVAILABLE: if not REQUESTS_AVAILABLE:
raise ImproperlyConfigured("Please install requests to use RequestsHttpConnection.") raise ImproperlyConfigured("Please install requests to use RequestsHttpConnection.")
+15 -3
View File
@@ -3,6 +3,14 @@ import urllib3
from urllib3.exceptions import ReadTimeoutError, SSLError as UrllibSSLError from urllib3.exceptions import ReadTimeoutError, SSLError as UrllibSSLError
import warnings import warnings
CA_CERTS = None
try:
import certifi
CA_CERTS = certifi.where()
except ImportError:
pass
from .base import Connection from .base import Connection
from ..exceptions import ConnectionError, ImproperlyConfigured, ConnectionTimeout, SSLError from ..exceptions import ConnectionError, ImproperlyConfigured, ConnectionTimeout, SSLError
from ..compat import urlencode from ..compat import urlencode
@@ -36,7 +44,7 @@ class Urllib3HttpConnection(Connection):
:arg headers: any custom http headers to be add to requests :arg headers: any custom http headers to be add to requests
""" """
def __init__(self, host='localhost', port=9200, http_auth=None, def __init__(self, host='localhost', port=9200, http_auth=None,
use_ssl=False, verify_certs=False, ca_certs=None, client_cert=None, use_ssl=False, verify_certs=True, ca_certs=None, client_cert=None,
client_key=None, ssl_version=None, ssl_assert_hostname=None, client_key=None, ssl_version=None, ssl_assert_hostname=None,
ssl_assert_fingerprint=None, maxsize=10, headers=None, **kwargs): ssl_assert_fingerprint=None, maxsize=10, headers=None, **kwargs):
@@ -48,6 +56,7 @@ class Urllib3HttpConnection(Connection):
http_auth = ':'.join(http_auth) http_auth = ':'.join(http_auth)
self.headers.update(urllib3.make_headers(basic_auth=http_auth)) self.headers.update(urllib3.make_headers(basic_auth=http_auth))
ca_certs = CA_CERTS if ca_certs is None else ca_certs
pool_class = urllib3.HTTPConnectionPool pool_class = urllib3.HTTPConnectionPool
kw = {} kw = {}
if use_ssl: if use_ssl:
@@ -59,14 +68,17 @@ class Urllib3HttpConnection(Connection):
}) })
if verify_certs: if verify_certs:
if not ca_certs:
raise ImproperlyConfigured("Root certificates are missing for certificate "
"validation. Either pass them in using the ca_certs parameter or "
"install certifi to use it automatically.")
kw.update({ kw.update({
'cert_reqs': 'CERT_REQUIRED', 'cert_reqs': 'CERT_REQUIRED',
'ca_certs': ca_certs, 'ca_certs': ca_certs,
'cert_file': client_cert, 'cert_file': client_cert,
'key_file': client_key, 'key_file': client_key,
}) })
elif ca_certs:
raise ImproperlyConfigured("You cannot pass CA certificates when verify SSL is off.")
else: else:
warnings.warn( warnings.warn(
'Connecting to %s using SSL with verify_certs=False is insecure.' % host) 'Connecting to %s using SSL with verify_certs=False is insecure.' % host)
+4 -4
View File
@@ -35,9 +35,9 @@ class TestUrllib3Connection(TestCase):
self.assertEquals({'authorization': 'Basic dXNlcm5hbWU6c2VjcmV0', self.assertEquals({'authorization': 'Basic dXNlcm5hbWU6c2VjcmV0',
'connection': 'keep-alive'}, con.headers) 'connection': 'keep-alive'}, con.headers)
def test_uses_https_if_specified(self): def test_uses_https_if_verify_certs_is_off(self):
with warnings.catch_warnings(record=True) as w: with warnings.catch_warnings(record=True) as w:
con = Urllib3HttpConnection(use_ssl=True) con = Urllib3HttpConnection(use_ssl=True, verify_certs=False)
self.assertEquals(1, len(w)) self.assertEquals(1, len(w))
self.assertEquals('Connecting to localhost using SSL with verify_certs=False is insecure.', str(w[0].message)) self.assertEquals('Connecting to localhost using SSL with verify_certs=False is insecure.', str(w[0].message))
@@ -86,9 +86,9 @@ class TestRequestsConnection(TestCase):
con = RequestsHttpConnection(timeout=42) con = RequestsHttpConnection(timeout=42)
self.assertEquals(42, con.timeout) self.assertEquals(42, con.timeout)
def test_use_https_if_specified(self): def test_uses_https_if_verify_certs_is_off(self):
with warnings.catch_warnings(record=True) as w: with warnings.catch_warnings(record=True) as w:
con = self._get_mock_connection({'use_ssl': True, 'url_prefix': 'url'}) con = self._get_mock_connection({'use_ssl': True, 'url_prefix': 'url', 'verify_certs': False})
self.assertEquals(1, len(w)) self.assertEquals(1, len(w))
self.assertEquals('Connecting to https://localhost:9200/url using SSL with verify_certs=False is insecure.', str(w[0].message)) self.assertEquals('Connecting to https://localhost:9200/url using SSL with verify_certs=False is insecure.', str(w[0].message))