Merge "Add a new option to enforce the OpenSSL FIPS mode"

This commit is contained in:
Zuul 2022-04-26 14:15:36 +00:00 committed by Gerrit Code Review
commit 64888bd05a
5 changed files with 98 additions and 0 deletions

View File

@ -267,3 +267,4 @@ Security Options
- :oslo.config:option:`oslo_messaging_rabbit.ssl_key_file`
- :oslo.config:option:`oslo_messaging_rabbit.ssl_cert_file`
- :oslo.config:option:`oslo_messaging_rabbit.rabbit_login_method`
- :oslo.config:option:`oslo_messaging_rabbit.ssl_enforce_fips_mode`

View File

@ -74,6 +74,15 @@ rabbit_opts = [
deprecated_name='kombu_ssl_ca_certs',
help='SSL certification authority file '
'(valid only if SSL enabled).'),
cfg.BoolOpt('ssl_enforce_fips_mode',
default=False,
help='Global toggle for enforcing the OpenSSL FIPS mode. '
'This feature requires Python support. '
'This is available in Python 3.9 in all '
'environments and may have been backported to older '
'Python versions on select environments. If the Python '
'executable used does not support OpenSSL FIPS mode, '
'an exception will be raised.'),
cfg.BoolOpt('heartbeat_in_pthread',
default=True,
help="Run the health check heartbeat thread "
@ -511,6 +520,7 @@ class Connection(object):
self.kombu_failover_strategy = driver_conf.kombu_failover_strategy
self.kombu_compression = driver_conf.kombu_compression
self.heartbeat_in_pthread = driver_conf.heartbeat_in_pthread
self.ssl_enforce_fips_mode = driver_conf.ssl_enforce_fips_mode
self.enable_cancel_on_failover = driver_conf.enable_cancel_on_failover
if self.heartbeat_in_pthread:
@ -548,6 +558,19 @@ class Connection(object):
self.ssl_cert_file = driver_conf.ssl_cert_file
self.ssl_ca_file = driver_conf.ssl_ca_file
if self.ssl_enforce_fips_mode:
if hasattr(ssl, 'FIPS_mode'):
LOG.info("Enforcing the use of the OpenSSL FIPS mode")
ssl.FIPS_mode_set(1)
else:
raise exceptions.ConfigurationError(
"OpenSSL FIPS mode is not supported by your Python "
"version. You must either change the Python "
"executable used to a version with FIPS mode "
"support or disable FIPS mode by setting the "
"'[oslo_messaging_rabbit] ssl_enforce_fips_mode' "
"configuration option to 'False'.")
self._url = ''
if url.hosts:
if url.transport.startswith('kombu+'):

View File

@ -47,3 +47,7 @@ class MessageUndeliverable(Exception):
self.exchange = exchange
self.routing_key = routing_key
self.message = message
class ConfigurationError(Exception):
"""Raised when messaging isn't configured correctly."""

View File

@ -31,6 +31,7 @@ import oslo_messaging
from oslo_messaging._drivers import amqpdriver
from oslo_messaging._drivers import common as driver_common
from oslo_messaging._drivers import impl_rabbit as rabbit_driver
from oslo_messaging.exceptions import ConfigurationError
from oslo_messaging.exceptions import MessageDeliveryFailure
from oslo_messaging.tests import utils as test_utils
from oslo_messaging.transport import DriverLoadFailure
@ -205,6 +206,65 @@ class TestRabbitDriverLoadSSL(test_utils.BaseTestCase):
)
class TestRabbitDriverLoadSSLWithFIPS(test_utils.BaseTestCase):
scenarios = [
('ssl_fips_mode', dict(options=dict(ssl=True,
ssl_enforce_fips_mode=True),
expected=True)),
]
@mock.patch('oslo_messaging._drivers.impl_rabbit.Connection'
'.ensure_connection')
@mock.patch('kombu.connection.Connection')
def test_driver_load_with_fips_supported(self,
connection_klass, fake_ensure):
self.config(ssl=True, ssl_enforce_fips_mode=True,
group="oslo_messaging_rabbit")
transport = oslo_messaging.get_transport(self.conf,
'kombu+memory:////')
self.addCleanup(transport.cleanup)
with mock.patch.object(ssl, 'FIPS_mode',
create=True, return_value=True):
with mock.patch.object(ssl, 'FIPS_mode_set', create=True):
connection = transport._driver._get_connection()
connection_klass.assert_called_once_with(
'memory:///', transport_options={
'client_properties': {
'capabilities': {
'connection.blocked': True,
'consumer_cancel_notify': True,
'authentication_failure_close': True,
},
'connection_name': connection.name},
'confirm_publish': True,
'on_blocked': mock.ANY,
'on_unblocked': mock.ANY},
ssl=self.expected, login_method='AMQPLAIN',
heartbeat=60, failover_strategy='round-robin'
)
@mock.patch('oslo_messaging._drivers.impl_rabbit.Connection'
'.ensure_connection')
@mock.patch('oslo_messaging._drivers.impl_rabbit.ssl')
@mock.patch('kombu.connection.Connection')
def test_fips_unsupported(self, connection_klass, fake_ssl, fake_ensure):
self.config(ssl=True, ssl_enforce_fips_mode=True,
group="oslo_messaging_rabbit")
transport = oslo_messaging.get_transport(self.conf,
'kombu+memory:////')
self.addCleanup(transport.cleanup)
del fake_ssl.FIPS_mode
# We do this test only if FIPS mode is not supported to
# ensure that we hard fail.
self.assertRaises(
ConfigurationError,
transport._driver._get_connection)
class TestRabbitPublisher(test_utils.BaseTestCase):
@mock.patch('kombu.messaging.Producer.publish')
def test_send_with_timeout(self, fake_publish):

View File

@ -0,0 +1,10 @@
---
features:
- |
Adding a new option, ``[oslo_messaging_rabbit] ssl_enforce_fips_mode``, to
the rabbitmq driver to enforce the OpenSSL FIPS mode if supported by the
version of Python.
security:
- |
We are now able to enforce the OpenSSL FIPS mode by using
``[oslo_messaging_rabbit] ssl_enforce_fips_mode``.