Fail if tls_enabled is True but backend does not support it

The tls_enabled option works properly only for the following backends.
 - oslo_cache.memcache_pool
 - dogpile.cache.bmemcache
 - dogpile.cache.pymemcache

Currently the tls options are all ignored in case a different backend
is used, but this does not allow users to notice that TLS is not
enabled contrary to their expectations.

This introduces the validation to ensure an appropriate backend is used
when tls is enabled.

NOTE:
The oslo_cache.memcache_pool bakcend supports tls_enabled only when
sasl_enabled is true, which can be fixed separately.

Change-Id: Ib967bf8cb21fb97fff94a6d6cb5983374e4798eb
This commit is contained in:
Takashi Kajinami 2024-01-31 23:39:10 +09:00
parent 33244f6aae
commit f1950fdaa9
2 changed files with 57 additions and 31 deletions

View File

@ -169,37 +169,49 @@ def _build_cache_config(conf):
conf_dict['%s.arguments.%s' % (prefix, arg)] = value conf_dict['%s.arguments.%s' % (prefix, arg)] = value
if conf.cache.tls_enabled: if conf.cache.tls_enabled:
_LOG.debug('Oslo Cache TLS - CA: %s', conf.cache.tls_cafile) if conf.cache.backend in ('dogpile.cache.bmemcache',
tls_context = ssl.create_default_context(cafile=conf.cache.tls_cafile) 'dogpile.cache.pymemcache',
'oslo_cache.memcache_pool'):
_LOG.debug('Oslo Cache TLS - CA: %s', conf.cache.tls_cafile)
tls_context = ssl.create_default_context(
cafile=conf.cache.tls_cafile)
if conf.cache.enforce_fips_mode: if conf.cache.enforce_fips_mode:
if hasattr(ssl, 'FIPS_mode'): if hasattr(ssl, 'FIPS_mode'):
_LOG.info("Enforcing the use of the OpenSSL FIPS mode") _LOG.info("Enforcing the use of the OpenSSL FIPS mode")
ssl.FIPS_mode_set(1) ssl.FIPS_mode_set(1)
else: else:
raise exception.ConfigurationError( raise exception.ConfigurationError(
"OpenSSL FIPS mode is not supported by your Python " "OpenSSL FIPS mode is not supported by your Python "
"version. You must either change the Python executable " "version. You must either change the Python "
"used to a version with FIPS mode support or disable " "executable used to a version with FIPS mode support "
"FIPS mode by setting the '[cache] enforce_fips_mode' " "or disable FIPS mode by setting "
"configuration option to 'False'.") "the '[cache] enforce_fips_mode' configuration option "
"to 'False'.")
if conf.cache.tls_certfile is not None: if conf.cache.tls_certfile is not None:
_LOG.debug('Oslo Cache TLS - cert: %s', conf.cache.tls_certfile) _LOG.debug('Oslo Cache TLS - cert: %s',
_LOG.debug('Oslo Cache TLS - key: %s', conf.cache.tls_keyfile) conf.cache.tls_certfile)
tls_context.load_cert_chain( _LOG.debug('Oslo Cache TLS - key: %s', conf.cache.tls_keyfile)
conf.cache.tls_certfile, tls_context.load_cert_chain(
conf.cache.tls_keyfile, conf.cache.tls_certfile,
conf.cache.tls_keyfile,
)
if conf.cache.tls_allowed_ciphers is not None:
_LOG.debug(
'Oslo Cache TLS - ciphers: %s',
conf.cache.tls_allowed_ciphers,
)
tls_context.set_ciphers(conf.cache.tls_allowed_ciphers)
conf_dict['%s.arguments.tls_context' % prefix] = tls_context
else:
msg = _(
"TLS setting via [cache] tls_enabled is not supported by this "
"backend."
) )
raise exception.ConfigurationError(msg)
if conf.cache.tls_allowed_ciphers is not None:
_LOG.debug(
'Oslo Cache TLS - ciphers: %s',
conf.cache.tls_allowed_ciphers,
)
tls_context.set_ciphers(conf.cache.tls_allowed_ciphers)
conf_dict['%s.arguments.tls_context' % prefix] = tls_context
# NOTE(hberaud): Pymemcache support socket keepalive, If it is enable in # NOTE(hberaud): Pymemcache support socket keepalive, If it is enable in
# our config then configure it to enable this feature. # our config then configure it to enable this feature.

View File

@ -324,7 +324,7 @@ class CacheRegionTest(test_cache.BaseTestCase):
self.config_fixture.config(group='cache', self.config_fixture.config(group='cache',
enabled=True, enabled=True,
config_prefix='test_prefix', config_prefix='test_prefix',
backend='oslo_cache.dict', backend='dogpile.cache.pymemcache',
tls_enabled=True, tls_enabled=True,
enforce_fips_mode=True) enforce_fips_mode=True)
@ -344,7 +344,7 @@ class CacheRegionTest(test_cache.BaseTestCase):
self.config_fixture.config(group='cache', self.config_fixture.config(group='cache',
enabled=True, enabled=True,
config_prefix='test_prefix', config_prefix='test_prefix',
backend='oslo_cache.dict', backend='dogpile.cache.pymemcache',
tls_enabled=True, tls_enabled=True,
enforce_fips_mode=True) enforce_fips_mode=True)
@ -355,7 +355,21 @@ class CacheRegionTest(test_cache.BaseTestCase):
# ensure that we hard fail. # ensure that we hard fail.
self.assertRaises(exception.ConfigurationError, self.assertRaises(exception.ConfigurationError,
cache._build_cache_config, cache._build_cache_config,
self.config_fixture.conf,) self.config_fixture.conf)
def test_cache_dictionary_config_builder_tls_enabled_unsupported(self):
"""Validate the tls_enabled opiton is not supported.."""
self.config_fixture.config(group='cache',
enabled=True,
config_prefix='test_prefix',
backend='oslo_cache.dict',
tls_enabled=True)
with mock.patch.object(ssl, 'create_default_context'):
self.assertRaises(exception.ConfigurationError,
cache._build_cache_config,
self.config_fixture.conf)
ssl.create_default_context.assert_not_called()
def test_cache_dictionary_config_builder_tls_enabled_with_config(self): def test_cache_dictionary_config_builder_tls_enabled_with_config(self):
"""Validate the backend is reset to default if caching is disabled.""" """Validate the backend is reset to default if caching is disabled."""