From 90c2b23fc075193b35a10725a6ef043aa4600eda Mon Sep 17 00:00:00 2001 From: Min RK Date: Thu, 4 Feb 2016 22:58:22 +0100 Subject: [PATCH 1/2] require confirmation for JupyterHub to run without SSL ensures folks deploying JupyterHub on HTTP have been told what's up. --- jupyterhub/app.py | 22 +++++++++++++++++++++- jupyterhub/tests/mocking.py | 1 + 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/jupyterhub/app.py b/jupyterhub/app.py index b8c0a1f0..054f7938 100644 --- a/jupyterhub/app.py +++ b/jupyterhub/app.py @@ -87,6 +87,9 @@ flags = { 'no-db': ({'JupyterHub': {'db_url': 'sqlite:///:memory:'}}, "disable persisting state database to disk" ), + 'no-ssl': ({'JupyterHub': {'confirm_no_ssl': True}}, + "Allow JupyterHub to run without SSL (SSL termination should be happening elsewhere)." + ), } SECRET_BYTES = 2048 # the number of bytes to use when generating new secrets @@ -208,7 +211,12 @@ class JupyterHub(Application): def _template_paths_default(self): return [os.path.join(self.data_files_path, 'templates')] - + + confirm_no_ssl = Bool(False, config=True, + help="""Confirm that JupyterHub should be run without SSL. + This is **NOT RECOMMENDED** unless SSL termination is being handled by another layer. + """ + ) ssl_key = Unicode('', config=True, help="""Path to SSL key file for the public facing interface of the proxy @@ -800,6 +808,18 @@ class JupyterHub(Application): cmd.extend(['--ssl-key', self.ssl_key]) if self.ssl_cert: cmd.extend(['--ssl-cert', self.ssl_cert]) + # Require SSL to be used or `--no-ssl` to confirm no SSL on + if ' --ssl' not in ' '.join(cmd): + if self.confirm_no_ssl: + self.log.warning("Running JupyterHub without SSL." + " There better be SSL termination happening somewhere else...") + else: + self.log.error( + "Refusing to run JuptyterHub without SSL." + " If you are terminating SSL in another layer," + " pass --no-ssl to tell JupyterHub to allow the proxy to listen on HTTP." + ) + self.exit(1) self.log.info("Starting proxy @ %s", self.proxy.public_server.bind_url) self.log.debug("Proxy cmd: %s", cmd) try: diff --git a/jupyterhub/tests/mocking.py b/jupyterhub/tests/mocking.py index df4c9e66..1866c2a1 100644 --- a/jupyterhub/tests/mocking.py +++ b/jupyterhub/tests/mocking.py @@ -109,6 +109,7 @@ class MockHub(JupyterHub): """Hub with various mock bits""" db_file = None + confirm_no_ssl = True def _ip_default(self): return localhost() From ce8d78222093646813c3fe461899bb2c2cabf64f Mon Sep 17 00:00:00 2001 From: Min RK Date: Thu, 4 Feb 2016 23:00:35 +0100 Subject: [PATCH 2/2] no-ssl in changelog --- docs/source/changelog.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/source/changelog.md b/docs/source/changelog.md index 797cf08e..8c397bd7 100644 --- a/docs/source/changelog.md +++ b/docs/source/changelog.md @@ -2,6 +2,12 @@ See `git log` for a more detailed summary. +## 0.5 + +- Single-user server must be run with Jupyter Notebook ≥ 4.0 +- Require `--no-ssl` confirmation to allow the Hub to be run without SSL (e.g. behind SSL termination in nginx) + + ## 0.4 ### 0.4.1