ceph/patches/0011-mgr-dashboard-remove-ability-to-create-and-check-TLS.patch
Thomas Lamprecht c6b34d0182 refresh patches and clean-up their context on current 19.2.0
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2024-11-07 09:12:47 +01:00

127 lines
5.6 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Max Carrara <m.carrara@proxmox.com>
Date: Fri, 26 Jan 2024 14:04:47 +0100
Subject: [PATCH] mgr/dashboard: remove ability to create and check TLS
key/cert pairs
In order to avoid running into PyO3-related issues [0] with PyOpenSSL,
the ability to create self-signed certs is disabled - the command
`ceph dashboard create-self-signed-cert` is made to always return an
error.
The command's error message contains the manual steps the user may
follow in order to set the certificate themselves, as well as a link
to the Ceph Dashboard documentation regarding TLS support. [1]
Furthermore, the check on start-up, that verifies that the configured
key/cert pair actually match, is also removed. This means that users
need to ensure themselves that the correct pair is supplied -
otherwise their browser will complain.
Other checks unrelated to the verification of keypairs are preserved,
such as checking for the cert's and key's existence on the filesystem.
`ssl.SSLError`s that occur during startup are re-raised with the
additional information they contain as `ServerConfigException`s, as
the dashboard handles these in its startup loop. Other exceptions are
re-raised as well. Otherwise, the dashboard will irrecoverably crash,
which also causes the `ceph dashboard` subcommand to stop working
altogether, even if one of its sub-subcommands are unrelated to the
dashboard itself.
These changes allow the dashboard to launch with TLS enabled again.
[0]: https://tracker.ceph.com/issues/63529
[1]: https://docs.ceph.com/en/reef/mgr/dashboard/#ssl-tls-support
Signed-off-by: Max Carrara <m.carrara@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
---
src/pybind/mgr/dashboard/module.py | 58 ++++++++++++++++++++++--------
1 file changed, 43 insertions(+), 15 deletions(-)
diff --git a/src/pybind/mgr/dashboard/module.py b/src/pybind/mgr/dashboard/module.py
index 41160b698aa..8f57061abe2 100644
--- a/src/pybind/mgr/dashboard/module.py
+++ b/src/pybind/mgr/dashboard/module.py
@@ -23,8 +23,7 @@ if TYPE_CHECKING:
from mgr_module import CLIReadCommand, CLIWriteCommand, HandleCommandResult, \
MgrModule, MgrStandbyModule, NotifyType, Option, _get_localized_key
-from mgr_util import ServerConfigException, build_url, \
- create_self_signed_cert, get_default_addr, verify_tls_files
+from mgr_util import ServerConfigException, build_url, get_default_addr
from . import mgr
from .controllers import Router, json_error_page
@@ -173,11 +172,29 @@ class CherryPyConfig(object):
else:
pkey_fname = self.get_localized_module_option('key_file') # type: ignore
- verify_tls_files(cert_fname, pkey_fname)
+ if not cert_fname or not pkey_fname:
+ raise ServerConfigException('no certificate configured')
+
+ if not os.path.isfile(cert_fname):
+ raise ServerConfigException(f"Certificate {cert_fname} does not exist")
+
+ if not os.path.isfile(pkey_fname):
+ raise ServerConfigException(f"private key {pkey_fname} does not exist")
+
+ try:
+ # 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)
+ except ssl.SSLError as e:
+ raise ServerConfigException(
+ "Encountered unexpected error while creating SSL context"
+ f" - library: {e.library}, reason: {e.reason}"
+ )
+ except Exception as e:
+ raise ServerConfigException(
+ f"Encountered unexpected error while creating SSL context: {e}"
+ )
- # 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_3
else:
@@ -468,15 +485,26 @@ class Module(MgrModule, CherryPyConfig):
@CLIWriteCommand("dashboard create-self-signed-cert")
def set_mgr_created_self_signed_cert(self):
- cert, pkey = create_self_signed_cert('IT', 'ceph-dashboard')
- result = HandleCommandResult(*self.set_ssl_certificate(inbuf=cert))
- if result.retval != 0:
- return result
-
- result = HandleCommandResult(*self.set_ssl_certificate_key(inbuf=pkey))
- if result.retval != 0:
- return result
- return 0, 'Self-signed certificate created', ''
+ from textwrap import dedent
+
+ err = """
+ Creating self-signed certificates is currently not available.
+ However, you can still set a key and certificate pair manually:
+
+ 1. Generate a private key and self-signed certificate:
+ # openssl req -newkey rsa:2048 -nodes -x509 \\
+ -keyout /root/dashboard-key.pem -out /root/dashboard-crt.pem -sha512 \\
+ -days 3650 -subj "/CN=IT/O=ceph-mgr-dashboard" -utf8
+
+ 2. Set the corresponding config keys for the key/cert pair:
+ # ceph config-key set mgr/dashboard/key -i /root/dashboard-key.pem
+ # ceph config-key set mgr/dashboard/crt -i /root/dashboard-crt.pem
+
+ For more information on how to configure TLS for the dashboard, visit:
+ https://docs.ceph.com/en/reef/mgr/dashboard/#ssl-tls-support
+ """
+
+ return -errno.ENOTSUP, '', dedent(err).strip()
@CLIWriteCommand("dashboard set-rgw-credentials")
def set_rgw_credentials(self):