From 21fbfc9c3a00edfe6063c33c738d49fdba21ea73 Mon Sep 17 00:00:00 2001 From: Wido den Hollander Date: Fri, 15 Jun 2018 16:39:09 +0200 Subject: [PATCH] mgr/dashboard: Add option to disable SSL Although is preferred and should be enabled by default users might want to disable SSL as the dashboard might be running behind a proxy which terminates the SSL. Fixes: https://tracker.ceph.com/issues/24674 Signed-off-by: Wido den Hollander --- doc/mgr/dashboard.rst | 23 ++++++++++++++++---- src/pybind/mgr/dashboard/controllers/docs.py | 12 ++++++++-- src/pybind/mgr/dashboard/module.py | 21 +++++++++++++----- 3 files changed, 45 insertions(+), 11 deletions(-) diff --git a/doc/mgr/dashboard.rst b/doc/mgr/dashboard.rst index 7d4dd084713..7950758ab90 100644 --- a/doc/mgr/dashboard.rst +++ b/doc/mgr/dashboard.rst @@ -85,7 +85,7 @@ Configuration SSL/TLS Support ^^^^^^^^^^^^^^^ -All HTTP connections to the dashboard are secured with SSL/TLS. +All HTTP connections to the dashboard are secured with SSL/TLS by default. To get the dashboard up and running quickly, you can generate and install a self-signed certificate using the following built-in command:: @@ -118,6 +118,20 @@ of the ``ceph-mgr`` instance, usually the hostname):: $ ceph config-key set mgr/dashboard/$name/crt -i dashboard.crt $ ceph config-key set mgr/dashboard/$name/key -i dashboard.key +SSL can also be disabled by setting this configuration value:: + + $ ceph config set mgr mgr/dashboard/ssl false + +This might be useful if the dashboard will be running behind a proxy which does +not support SSL for its upstream servers or other situations where SSL is not +wanted or required. + +.. warning:: + + Use caution when disabling SSL as usernames and passwords will be sent to the + dashboard unencrypted. + + .. note:: You need to restart the Ceph manager processes manually after changing the SSL @@ -134,9 +148,10 @@ Host name and port Like most web applications, dashboard binds to a TCP/IP address and TCP port. By default, the ``ceph-mgr`` daemon hosting the dashboard (i.e., the currently -active manager) will bind to TCP port 8443. If no specific address has been -configured, the web app will bind to ``::``, which corresponds to all available -IPv4 and IPv6 addresses. +active manager) will bind to TCP port 8443 or 8080 when SSL is disabled. + +If no specific address has been configured, the web app will bind to ``::``, +which corresponds to all available IPv4 and IPv6 addresses. These defaults can be changed via the configuration key facility on a cluster-wide level (so they apply to all manager instances) as follows:: diff --git a/src/pybind/mgr/dashboard/controllers/docs.py b/src/pybind/mgr/dashboard/controllers/docs.py index 3438c839997..2998c0cbc63 100644 --- a/src/pybind/mgr/dashboard/controllers/docs.py +++ b/src/pybind/mgr/dashboard/controllers/docs.py @@ -1,10 +1,12 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import +from distutils.util import strtobool + import cherrypy from . import Controller, BaseController, Endpoint, ENDPOINT_MAP -from .. import logger +from .. import logger, mgr @Controller('/docs') @@ -171,6 +173,12 @@ class Docs(BaseController): if not baseUrl: baseUrl = "/" + + scheme = 'https' + ssl = strtobool(mgr.get_localized_config('ssl', 'True')) + if not ssl: + scheme = 'http' + spec = { 'swagger': "2.0", 'info': { @@ -186,7 +194,7 @@ class Docs(BaseController): 'host': host, 'basePath': baseUrl, 'tags': self._gen_tags(all_endpoints), - 'schemes': ["https"], + 'schemes': [scheme], 'paths': paths } diff --git a/src/pybind/mgr/dashboard/module.py b/src/pybind/mgr/dashboard/module.py index f6eddf71c09..65454eb396d 100644 --- a/src/pybind/mgr/dashboard/module.py +++ b/src/pybind/mgr/dashboard/module.py @@ -6,6 +6,7 @@ from __future__ import absolute_import import errno from distutils.version import StrictVersion +from distutils.util import strtobool import os import socket import tempfile @@ -116,7 +117,12 @@ class SSLCherryPyConfig(object): :returns our URI """ server_addr = self.get_localized_config('server_addr', '::') - server_port = self.get_localized_config('server_port', '8443') + ssl = strtobool(self.get_localized_config('ssl', 'True')) + def_server_port = 8443 + if not ssl: + def_server_port = 8080 + + server_port = self.get_localized_config('server_port', def_server_port) if server_addr is None: raise ServerConfigException( 'no server_addr configured; ' @@ -163,18 +169,22 @@ class SSLCherryPyConfig(object): 'engine.autoreload.on': False, 'server.socket_host': server_addr, 'server.socket_port': int(server_port), - 'server.ssl_module': 'builtin', - 'server.ssl_certificate': cert_fname, - 'server.ssl_private_key': pkey_fname, 'error_page.default': json_error_page, 'tools.request_logging.on': True } + + if ssl: + config['server.ssl_module'] = 'builtin' + config['server.ssl_certificate'] = cert_fname + config['server.ssl_private_key'] = pkey_fname + cherrypy.config.update(config) self._url_prefix = prepare_url_prefix(self.get_config('url_prefix', default='')) - uri = "https://{0}:{1}{2}/".format( + uri = "{0}://{1}:{2}{3}/".format( + 'https' if ssl else 'http', socket.getfqdn() if server_addr == "::" else server_addr, server_port, self.url_prefix @@ -233,6 +243,7 @@ class Module(MgrModule, SSLCherryPyConfig): {'name': 'username'}, {'name': 'key_file'}, {'name': 'crt_file'}, + {'name': 'ssl'} ] OPTIONS.extend(options_schema_list())