]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: Disable TLS 1.0 and 1.1 38332/head
authorVolker Theile <vtheile@suse.com>
Wed, 25 Nov 2020 16:57:13 +0000 (17:57 +0100)
committerVolker Theile <vtheile@suse.com>
Thu, 7 Jan 2021 08:50:23 +0000 (09:50 +0100)
Disable these TLS versions because of security issues.

Fixes: https://tracker.ceph.com/issues/48360
Signed-off-by: Volker Theile <vtheile@suse.com>
(cherry picked from commit 5cf222b6d2a5cdc7ff23357b12878d34a4e68801)

Conflicts:
- src/pybind/mgr/dashboard/module.py
Limiting TLS version seems to work only with CherryPy >= 8.9.1 (Ubuntu 18.04 or SUSE Leap 15.1) based on tests in Teuthology. It failed on Ubuntu 16.04 (CherryPy 3.5.0) and RHEL 7.9 (CherryPy 3.2.2).
- qa/tasks/mgr/test_dashboard.py
Tests must be removed because they will not work in Teuthology because of outdated cherrypy versions on most platforms. Only Ubuntu 18.04 (and downstream SUSE Leap 15.1) will work, but it's not possible to limit QA runs to that specific platforms.

src/pybind/mgr/dashboard/module.py

index 132eea006542addcca8e773bec436d51a9cf5a1b..ab78c8c697b2ff0518b3ee58aa43863e3d3e7de2 100644 (file)
@@ -5,9 +5,12 @@ ceph dashboard mgr plugin (based on CherryPy)
 from __future__ import absolute_import
 
 import collections
+from distutils.version import StrictVersion
 import errno
 import os
 import socket
+import ssl
+import sys
 import tempfile
 import threading
 import time
@@ -103,8 +106,8 @@ class CherryPyConfig(object):
         """
         server_addr = self.get_localized_module_option(
             'server_addr', get_default_addr())
-        ssl = self.get_localized_module_option('ssl', True)
-        if not ssl:
+        use_ssl = self.get_localized_module_option('ssl', True)
+        if not use_ssl:
             server_port = self.get_localized_module_option('server_port', 8080)
         else:
             server_port = self.get_localized_module_option('ssl_server_port', 8443)
@@ -114,7 +117,7 @@ class CherryPyConfig(object):
                 'no server_addr configured; '
                 'try "ceph config set mgr mgr/{}/{}/server_addr <ip>"'
                 .format(self.module_name, self.get_mgr_id()))
-        self.log.info('server: ssl=%s host=%s port=%d', 'yes' if ssl else 'no',
+        self.log.info('server: ssl=%s host=%s port=%d', 'yes' if use_ssl else 'no',
                       server_addr, server_port)
 
         # Initialize custom handlers.
@@ -147,7 +150,7 @@ class CherryPyConfig(object):
             'tools.plugin_hooks_filter_request.on': True,
         }
 
-        if ssl:
+        if use_ssl:
             # SSL initialization
             cert = self.get_store("crt")
             if cert is not None:
@@ -169,9 +172,22 @@ class CherryPyConfig(object):
 
             verify_tls_files(cert_fname, pkey_fname)
 
+            # Create custom SSL context to disable TLS 1.0 and 1.1.
+            context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
+            context.load_cert_chain(cert_fname, pkey_fname)
+            if sys.version_info >= (3, 7):
+                context.minimum_version = ssl.TLSVersion.TLSv1_2
+            else:
+                # Based on tests limiting TLS to specific versions
+                # starts working with CherryPy >= 8.9.1 (Ubuntu 18.04
+                # or SUSE Leap 15.1).
+                if StrictVersion(cherrypy.__version__) >= StrictVersion('8.9.1'):
+                    context.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1
+
             config['server.ssl_module'] = 'builtin'
             config['server.ssl_certificate'] = cert_fname
             config['server.ssl_private_key'] = pkey_fname
+            config['server.ssl_context'] = context
 
         self.update_cherrypy_config(config)
 
@@ -179,7 +195,7 @@ class CherryPyConfig(object):
                                                                      default=''))
 
         uri = "{0}://{1}:{2}{3}/".format(
-            'https' if ssl else 'http',
+            'https' if use_ssl else 'http',
             socket.getfqdn(server_addr if server_addr != '::' else ''),
             server_port,
             self.url_prefix