Merge "Add minimum TLS version option in octavia.conf"

This commit is contained in:
Zuul 2020-06-29 22:47:36 +00:00 committed by Gerrit Code Review
commit 179f00e839
7 changed files with 93 additions and 5 deletions

View File

@ -80,6 +80,10 @@
# pools. Available versions: SSLv3, TLSv1, TLSv1.1, TLSv1.2, TLSv1.3
# default_pool_tls_versions = TLSv1.2, TLSv1.3
# Minimum TLS version to allow for listeners, pools, or the defaults for
# either. Available versions: SSLv3, TLSv1, TLSv1.1, TLSv1.2, TLSv1.3
# minimum_tls_version =
[database]
# This line MUST be changed to actually run the plugin.
# Example:

View File

@ -288,9 +288,11 @@ class ListenersController(base.BaseController):
vip_address = vip_db.ip_address
self._validate_cidr_compatible_with_vip(vip_address, allowed_cidrs)
# Validate TLS version list
if listener_protocol == constants.PROTOCOL_TERMINATED_HTTPS:
# Validate TLS version list
validate.check_tls_version_list(listener_dict['tls_versions'])
# Validate TLS versions against minimum
validate.check_tls_version_min(listener_dict['tls_versions'])
try:
db_listener = self.repositories.listener.create(
@ -498,9 +500,11 @@ class ListenersController(base.BaseController):
'The following ciphers have been blacklisted by an '
'administrator: ' + ', '.join(rejected_ciphers)))
# Validate TLS version list
if listener.tls_versions is not wtypes.Unset:
# Validate TLS version list
validate.check_tls_version_list(listener.tls_versions)
# Validate TLS versions against minimum
validate.check_tls_version_min(listener.tls_versions)
def _set_default_on_none(self, listener):
"""Reset settings to their default values if None/null was passed in

View File

@ -131,9 +131,11 @@ class PoolsController(base.BaseController):
'The following ciphers have been blacklisted by an '
'administrator: ' + ', '.join(rejected_ciphers)))
# Validate TLS version list
if pool_dict['tls_enabled']:
# Validate TLS version list
validate.check_tls_version_list(pool_dict['tls_versions'])
# Validate TLS versions against minimum
validate.check_tls_version_min(pool_dict['tls_versions'])
try:
return self.repositories.create_pool_on_load_balancer(
@ -403,9 +405,11 @@ class PoolsController(base.BaseController):
"The following ciphers have been blacklisted by an "
"administrator: " + ', '.join(rejected_ciphers)))
# Validate TLS version list
if pool.tls_versions is not wtypes.Unset:
# Validate TLS version list
validate.check_tls_version_list(pool.tls_versions)
# Validate TLS version against minimum
validate.check_tls_version_min(pool.tls_versions)
@wsme_pecan.wsexpose(pool_types.PoolRootResponse, wtypes.text,
body=pool_types.PoolRootPut, status_code=200)

View File

@ -123,7 +123,11 @@ api_opts = [
cfg.ListOpt('default_pool_tls_versions',
default=constants.TLS_VERSIONS_OWASP_SUITE_B,
help=_('List of TLS versions to use for new TLS-enabled '
'pools.'))
'pools.')),
cfg.StrOpt('minimum_tls_version',
default=None,
choices=constants.TLS_ALL_VERSIONS + [None],
help=_('Minimum allowed TLS version for listeners and pools.'))
]
# Options only used by the amphora agent
@ -875,6 +879,7 @@ def init(args, **kwargs):
version='%%prog %s' % version.version_info.release_string(),
**kwargs)
handle_deprecation_compatibility()
validate.check_default_tls_versions_min_conflict()
setup_remote_debugger()
validate.check_default_ciphers_blacklist_conflict()

View File

@ -471,3 +471,40 @@ def check_tls_version_list(versions):
if invalid_versions:
raise exceptions.ValidationException(
detail=_('Invalid TLS versions: ' + ', '.join(invalid_versions)))
def check_tls_version_min(versions, message=None):
"""Checks a TLS version string against the configured minimum."""
if not CONF.api_settings.minimum_tls_version:
return
if not message:
message = _("Requested TLS versions are less than the minimum: ")
min_ver_index = constants.TLS_ALL_VERSIONS.index(
CONF.api_settings.minimum_tls_version)
rejected = []
for ver in versions:
if constants.TLS_ALL_VERSIONS.index(ver) < min_ver_index:
rejected.append(ver)
if rejected:
raise exceptions.ValidationException(detail=(
message + ', '.join(rejected) + " < " +
CONF.api_settings.minimum_tls_version))
def check_default_tls_versions_min_conflict():
if not CONF.api_settings.minimum_tls_version:
return
listener_message = _("Default listener TLS versions are less than the "
"minimum: ")
pool_message = _("Default pool TLS versions are less than the minimum: ")
check_tls_version_min(CONF.api_settings.default_listener_tls_versions,
message=listener_message)
check_tls_version_min(CONF.api_settings.default_pool_tls_versions,
message=pool_message)

View File

@ -484,3 +484,31 @@ class TestValidations(base.TestCase):
exceptions.ValidationException,
validate.check_tls_version_list,
[])
def test_check_tls_version_min(self):
self.conf.config(group="api_settings", minimum_tls_version='TLSv1.2')
# Test valid list
validate.check_tls_version_min(['TLSv1.2', 'TLSv1.3'])
# Test invalid list
self.assertRaises(exceptions.ValidationException,
validate.check_tls_version_min,
['TLSv1', 'TLSv1.1', 'TLSv1.2'])
def test_check_default_tls_versions_min_conflict(self):
self.conf.config(group="api_settings", minimum_tls_version='TLSv1.2')
# Test conflict in listener default
self.conf.config(group="api_settings", default_listener_tls_versions=[
'SSLv3', 'TLSv1.2'])
self.assertRaises(exceptions.ValidationException,
validate.check_default_tls_versions_min_conflict)
# Test conflict in pool default
self.conf.config(group="api_settings", default_listener_tls_versions=[
'TLSv1.2'])
self.conf.config(group="api_settings", default_pool_tls_versions=[
'TLSv1', 'TLSv1.3'])
self.assertRaises(exceptions.ValidationException,
validate.check_default_tls_versions_min_conflict)

View File

@ -0,0 +1,6 @@
---
features:
- |
Added ``minimum_tls_version`` to ``octavia.conf``. Listeners, pools, and
the defaults for either will be blocked from using any lower TLS versions.
By default, there is no minumum version.