From 73f1d9f5d5d0d6673313323d08e90a1ad9b0c968 Mon Sep 17 00:00:00 2001 From: steveny91 Date: Thu, 26 Dec 2024 12:48:01 -0500 Subject: [PATCH 1/4] allow SSLContext ciphers to be customized --- datadog_checks_base/changelog.d/19055.added | 1 + .../datadog_checks/base/utils/tls.py | 10 ++++ .../tests/base/utils/test_tls.py | 58 +++++++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 datadog_checks_base/changelog.d/19055.added diff --git a/datadog_checks_base/changelog.d/19055.added b/datadog_checks_base/changelog.d/19055.added new file mode 100644 index 0000000000000..6d5b7d493ce88 --- /dev/null +++ b/datadog_checks_base/changelog.d/19055.added @@ -0,0 +1 @@ +Allow for Ciphers to be customizable in the SSLContext creation diff --git a/datadog_checks_base/datadog_checks/base/utils/tls.py b/datadog_checks_base/datadog_checks/base/utils/tls.py index 56b6f9b0b5534..0fb43c028a112 100644 --- a/datadog_checks_base/datadog_checks/base/utils/tls.py +++ b/datadog_checks_base/datadog_checks/base/utils/tls.py @@ -28,6 +28,7 @@ 'tls_private_key': None, 'tls_private_key_password': None, 'tls_validate_hostname': True, + 'tls_ciphers': 'ALL', } @@ -115,6 +116,15 @@ def _create_tls_context(self): else: context.check_hostname = False + ciphers = self.config.get('tls_ciphers') + if ciphers: + if 'ALL' in ciphers: + updated_ciphers = "ALL" + else: + updated_ciphers = ":".join(ciphers) + + context.set_ciphers(updated_ciphers) + # https://docs.python.org/3/library/ssl.html#ssl.SSLContext.load_verify_locations # https://docs.python.org/3/library/ssl.html#ssl.SSLContext.load_default_certs ca_cert = self.config['tls_ca_cert'] diff --git a/datadog_checks_base/tests/base/utils/test_tls.py b/datadog_checks_base/tests/base/utils/test_tls.py index a7214190ec2e4..91a555950690a 100644 --- a/datadog_checks_base/tests/base/utils/test_tls.py +++ b/datadog_checks_base/tests/base/utils/test_tls.py @@ -299,6 +299,64 @@ def test_client_key_expanded_tls_verify_false(self): check.get_tls_context() mock_expand.assert_called_with('~/foo') + @pytest.mark.parametrize( + 'instance,expected_ciphers', + [ + pytest.param( + {'tls_verify': False}, + 'ALL', + id="Construct ciphers with no config", + ), + pytest.param( + {'tls_ciphers': ['PSK-CAMELLIA128-SHA256', 'DHE-PSK-CAMELLIA128-SHA256']}, + 'PSK-CAMELLIA128-SHA256:DHE-PSK-CAMELLIA128-SHA256', + id='Construct ciphers with specific ciphers', + ), + pytest.param( + {'tls_ciphers': ['ALL']}, + 'ALL', + id="Construct Ciphers with 'ALL' ciphers", + ), + ], + ) + def test_cipher_construction(self, instance, expected_ciphers): + with patch.object(ssl.SSLContext, 'set_ciphers') as mock_set_ciphers: + check = AgentCheck('test', {}, [instance]) + check.get_tls_context() + mock_set_ciphers.assert_called_once_with(expected_ciphers) + + @pytest.mark.parametrize( + 'instance,expected_ciphers', + [ + pytest.param( + {'tls_verify': False}, + 'ALL', + id="No Ciphers, default to 'ALL'", + ), + pytest.param( + {'tls_ciphers': ['PSK-CAMELLIA128-SHA256', 'DHE-PSK-CAMELLIA128-SHA256']}, + 'PSK-CAMELLIA128-SHA256:DHE-PSK-CAMELLIA128-SHA256', + id='Add specific ciphers only', + ), + pytest.param( + {'tls_ciphers': ['ALL']}, + 'ALL', + id="'ALL' manually", + ), + ], + ) + def test_ciphers(self, instance, expected_ciphers): + check = AgentCheck('test', {}, [instance]) + context = check.get_tls_context() + + expected_context = ssl.SSLContext(protocol=ssl.PROTOCOL_TLS_CLIENT) + expected_context.set_ciphers(expected_ciphers) + + actual_ciphers = sorted(cipher['name'] for cipher in context.get_ciphers()) + expected_ciphers_list = sorted(cipher['name'] for cipher in expected_context.get_ciphers()) + + assert actual_ciphers == expected_ciphers_list + class TestTLSContextOverrides: def test_override_context(self): From cffe0a4e1a0e658751c9e88c85f87c265baac85a Mon Sep 17 00:00:00 2001 From: Steven Yuen Date: Thu, 26 Dec 2024 12:55:51 -0500 Subject: [PATCH 2/4] Rename 19055.added to 19312.added --- datadog_checks_base/changelog.d/{19055.added => 19312.added} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename datadog_checks_base/changelog.d/{19055.added => 19312.added} (100%) diff --git a/datadog_checks_base/changelog.d/19055.added b/datadog_checks_base/changelog.d/19312.added similarity index 100% rename from datadog_checks_base/changelog.d/19055.added rename to datadog_checks_base/changelog.d/19312.added From c6c6593f5b3d3a8f12e59143bb90da88703a69b8 Mon Sep 17 00:00:00 2001 From: Steven Yuen Date: Thu, 26 Dec 2024 13:46:19 -0500 Subject: [PATCH 3/4] Update test_tls.py --- datadog_checks_base/tests/base/utils/test_tls.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/datadog_checks_base/tests/base/utils/test_tls.py b/datadog_checks_base/tests/base/utils/test_tls.py index 91a555950690a..8f3dc7848f2fc 100644 --- a/datadog_checks_base/tests/base/utils/test_tls.py +++ b/datadog_checks_base/tests/base/utils/test_tls.py @@ -308,8 +308,8 @@ def test_client_key_expanded_tls_verify_false(self): id="Construct ciphers with no config", ), pytest.param( - {'tls_ciphers': ['PSK-CAMELLIA128-SHA256', 'DHE-PSK-CAMELLIA128-SHA256']}, - 'PSK-CAMELLIA128-SHA256:DHE-PSK-CAMELLIA128-SHA256', + {'tls_ciphers': ['TLS_RSA_WITH_SEED_CBC_SHA', 'TLS_SM4_GCM_SM3',]}, + 'TLS_RSA_WITH_SEED_CBC_SHA:TLS_SM4_GCM_SM3', id='Construct ciphers with specific ciphers', ), pytest.param( From fe86b31af7b1ecb38d72ad489cb297c1ca1914d4 Mon Sep 17 00:00:00 2001 From: Steven Yuen Date: Thu, 26 Dec 2024 13:46:43 -0500 Subject: [PATCH 4/4] Update test_tls.py --- datadog_checks_base/tests/base/utils/test_tls.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datadog_checks_base/tests/base/utils/test_tls.py b/datadog_checks_base/tests/base/utils/test_tls.py index 8f3dc7848f2fc..26979b9d25b6a 100644 --- a/datadog_checks_base/tests/base/utils/test_tls.py +++ b/datadog_checks_base/tests/base/utils/test_tls.py @@ -308,7 +308,7 @@ def test_client_key_expanded_tls_verify_false(self): id="Construct ciphers with no config", ), pytest.param( - {'tls_ciphers': ['TLS_RSA_WITH_SEED_CBC_SHA', 'TLS_SM4_GCM_SM3',]}, + {'tls_ciphers': ['TLS_RSA_WITH_SEED_CBC_SHA', 'TLS_SM4_GCM_SM3']}, 'TLS_RSA_WITH_SEED_CBC_SHA:TLS_SM4_GCM_SM3', id='Construct ciphers with specific ciphers', ),