From: Volker Theile Date: Wed, 25 Nov 2020 16:57:13 +0000 (+0100) Subject: mgr/dashboard: Disable TLS 1.0 and 1.1 X-Git-Tag: v14.2.17~107^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=8de58bf7b9381acded4bbbc4d6ab20a611ec66e1;p=ceph.git mgr/dashboard: Disable TLS 1.0 and 1.1 Disable these TLS versions because of security issues. Fixes: https://tracker.ceph.com/issues/48360 Signed-off-by: Volker Theile (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. --- diff --git a/src/pybind/mgr/dashboard/module.py b/src/pybind/mgr/dashboard/module.py index 132eea006542..ab78c8c697b2 100644 --- a/src/pybind/mgr/dashboard/module.py +++ b/src/pybind/mgr/dashboard/module.py @@ -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 "' .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