diff --git a/Changelog.rst b/Changelog.rst index a55f1e8d8..ad7ba9a6d 100644 --- a/Changelog.rst +++ b/Changelog.rst @@ -6,6 +6,8 @@ Changelog 6.4.0 (dev) ----------- * Removed deprecated option ``update_all_types``. + * Using insecure SSL configuration (``verify_cert=False``) raises a warning, this can + be not showed with ``ssl_show_warn=False`` 6.3.0 (2018-06-20) ----------- diff --git a/elasticsearch/client/__init__.py b/elasticsearch/client/__init__.py index c0058a669..1f493f5cc 100644 --- a/elasticsearch/client/__init__.py +++ b/elasticsearch/client/__init__.py @@ -123,6 +123,20 @@ class Elasticsearch(object): ca_certs='/path/to/CA_certs' ) + If using SSL, but don't verify the certs, a warning message is showed + optionally (see :class:`~elasticsearch.Urllib3HttpConnection` for + detailed description of the options):: + + es = Elasticsearch( + ['localhost:443', 'other_host:443'], + # turn on SSL + use_ssl=True, + # no verify SSL certificates + verify_certs=False, + # don't show warnings about ssl certs verification + ssl_show_warn=False + ) + SSL client authentication is supported (see :class:`~elasticsearch.Urllib3HttpConnection` for detailed description of the options):: diff --git a/elasticsearch/connection/http_requests.py b/elasticsearch/connection/http_requests.py index b98e7772c..1e590fbc3 100644 --- a/elasticsearch/connection/http_requests.py +++ b/elasticsearch/connection/http_requests.py @@ -18,6 +18,7 @@ class RequestsHttpConnection(Connection): string or a tuple. Any value will be passed into requests as `auth`. :arg use_ssl: use ssl for the connection if `True` :arg verify_certs: whether to verify SSL certificates + :arg ssl_show_warn: show warning when verify certs is disabled :arg ca_certs: optional path to CA bundle. By default standard requests' bundle will be used. :arg client_cert: path to the file containing the private key and the @@ -27,7 +28,7 @@ class RequestsHttpConnection(Connection): :arg headers: any custom http headers to be add to requests """ def __init__(self, host='localhost', port=9200, http_auth=None, - use_ssl=False, verify_certs=True, ca_certs=None, client_cert=None, + use_ssl=False, verify_certs=True, ssl_show_warn=True, ca_certs=None, client_cert=None, client_key=None, headers=None, **kwargs): if not REQUESTS_AVAILABLE: raise ImproperlyConfigured("Please install requests to use RequestsHttpConnection.") @@ -57,7 +58,7 @@ def __init__(self, host='localhost', port=9200, http_auth=None, raise ImproperlyConfigured("You cannot pass CA certificates when verify SSL is off.") self.session.verify = ca_certs - if self.use_ssl and not verify_certs: + if self.use_ssl and not verify_certs and ssl_show_warn: warnings.warn( 'Connecting to %s using SSL with verify_certs=False is insecure.' % self.base_url) diff --git a/elasticsearch/connection/http_urllib3.py b/elasticsearch/connection/http_urllib3.py index 9d78c9185..90452fa2e 100644 --- a/elasticsearch/connection/http_urllib3.py +++ b/elasticsearch/connection/http_urllib3.py @@ -48,6 +48,7 @@ class Urllib3HttpConnection(Connection): string or a tuple :arg use_ssl: use ssl for the connection if `True` :arg verify_certs: whether to verify SSL certificates + :arg ssl_show_warn: show warning when verify certs is disabled :arg ca_certs: optional path to CA bundle. See https://urllib3.readthedocs.io/en/latest/security.html#using-certifi-with-urllib3 for instructions how to get default set @@ -67,7 +68,7 @@ class Urllib3HttpConnection(Connection): :arg http_compress: Use gzip compression """ def __init__(self, host='localhost', port=9200, http_auth=None, - use_ssl=False, verify_certs=VERIFY_CERTS_DEFAULT, ca_certs=None, client_cert=None, + use_ssl=False, verify_certs=VERIFY_CERTS_DEFAULT, ssl_show_warn=True, ca_certs=None, client_cert=None, client_key=None, ssl_version=None, ssl_assert_hostname=None, ssl_assert_fingerprint=None, maxsize=10, headers=None, ssl_context=None, http_compress=False, **kwargs): @@ -131,8 +132,9 @@ def __init__(self, host='localhost', port=9200, http_auth=None, 'key_file': client_key, }) else: - warnings.warn( - 'Connecting to %s using SSL with verify_certs=False is insecure.' % host) + if ssl_show_warn: + warnings.warn( + 'Connecting to %s using SSL with verify_certs=False is insecure.' % host) self.pool = pool_class(host, port=port, timeout=self.timeout, maxsize=maxsize, **kw) diff --git a/test_elasticsearch/test_connection.py b/test_elasticsearch/test_connection.py index 430d43cbc..d35387542 100644 --- a/test_elasticsearch/test_connection.py +++ b/test_elasticsearch/test_connection.py @@ -74,6 +74,13 @@ def test_uses_https_if_verify_certs_is_off(self): self.assertIsInstance(con.pool, urllib3.HTTPSConnectionPool) + def nowarn_when_test_uses_https_if_verify_certs_is_off(self): + with warnings.catch_warnings(record=True) as w: + con = Urllib3HttpConnection(use_ssl=True, verify_certs=False, ssl_show_warn=False) + self.assertEquals(0, len(w)) + + self.assertIsInstance(con.pool, urllib3.HTTPSConnectionPool) + def test_doesnt_use_https_if_not_specified(self): con = Urllib3HttpConnection() self.assertIsInstance(con.pool, urllib3.HTTPConnectionPool) @@ -129,6 +136,17 @@ def test_uses_https_if_verify_certs_is_off(self): self.assertEquals('GET', request.method) self.assertEquals(None, request.body) + def nowarn_when_test_uses_https_if_verify_certs_is_off(self): + with warnings.catch_warnings(record=True) as w: + con = self._get_mock_connection({'use_ssl': True, 'url_prefix': 'url', 'verify_certs': False, 'ssl_show_warn': False}) + self.assertEquals(0, len(w)) + + request = self._get_request(con, 'GET', '/') + + self.assertEquals('https://localhost:9200/url/', request.url) + self.assertEquals('GET', request.method) + self.assertEquals(None, request.body) + def test_merge_headers(self): con = self._get_mock_connection(connection_params={'headers': {'h1': 'v1', 'h2': 'v2'}}) req = self._get_request(con, 'GET', '/', headers={'h2': 'v2p', 'h3': 'v3'})