Security settings#
Important
You should not run JupyterHub without SSL encryption on a public network.
Security is the most important aspect of configuring Jupyter. Three (3) configuration settings are the main aspects of security configuration:
SSL encryption (to enable HTTPS)
Cookie secret (a key for encrypting browser cookies)
Proxy authentication token (used for the Hub and other services to authenticate to the Proxy)
The Hub hashes all secrets (e.g. auth tokens) before storing them in its database. A loss of control over read-access to the database should have minimal impact on your deployment. If your database has been compromised, it is still a good idea to revoke existing tokens.
Enabling SSL encryption#
Since JupyterHub includes authentication and allows arbitrary code execution, you should not run it without SSL (HTTPS).
Using an SSL certificate#
This will require you to obtain an official, trusted SSL certificate or create a
self-signed certificate. Once you have obtained and installed a key and
certificate, you need to specify their locations in the jupyterhub_config.py
configuration file as follows:
c.JupyterHub.ssl_key = '/path/to/my.key'
c.JupyterHub.ssl_cert = '/path/to/my.cert'
Some cert files also contain the key, in which case only the cert is needed. It is important that these files be put in a secure location on your server, where they are not readable by regular users.
If you are using a chain certificate, see also chained certificate for SSL in the JupyterHub Troubleshooting FAQ.
Using letsencrypt#
It is also possible to use letsencrypt to obtain
a free, trusted SSL certificate. If you run letsencrypt using the default
options, the needed configuration is (replace mydomain.tld
by your fully
qualified domain name):
c.JupyterHub.ssl_key = '/etc/letsencrypt/live/{mydomain.tld}/privkey.pem'
c.JupyterHub.ssl_cert = '/etc/letsencrypt/live/{mydomain.tld}/fullchain.pem'
If the fully qualified domain name (FQDN) is example.com
, the following
would be the needed configuration:
c.JupyterHub.ssl_key = '/etc/letsencrypt/live/example.com/privkey.pem'
c.JupyterHub.ssl_cert = '/etc/letsencrypt/live/example.com/fullchain.pem'
If SSL termination happens outside of the Hub#
In certain cases, for example, if the hub is running behind a reverse proxy, and SSL termination is being provided by NGINX, it is reasonable to run the hub without SSL.
To achieve this, remove c.JupyterHub.ssl_key
and c.JupyterHub.ssl_cert
from your configuration (setting them to None
or an empty string does not
have the same effect, and will result in an error).
Proxy authentication token#
The Hub authenticates its requests to the Proxy using a secret token that
the Hub and Proxy agree upon. Note that this applies to the default
ConfigurableHTTPProxy
implementation. Not all proxy implementations
use an auth token.
The value of this token should be a random string (for example, generated by
openssl rand -hex 32
). You can store it in the configuration file or an
environment variable.
Generating and storing token in the configuration file#
You can set the value in the configuration file, jupyterhub_config.py
:
c.ConfigurableHTTPProxy.api_token = 'abc123...' # any random string
Generating and storing as an environment variable#
You can pass this value of the proxy authentication token to the Hub and Proxy
using the CONFIGPROXY_AUTH_TOKEN
environment variable:
export CONFIGPROXY_AUTH_TOKEN=$(openssl rand -hex 32)
This environment variable needs to be visible to the Hub and Proxy.
Default if token is not set#
If you do not set the Proxy authentication token, the Hub will generate a random key itself. This means that any time you restart the Hub, you must also restart the Proxy. If the proxy is a subprocess of the Hub, this should happen automatically (this is the default configuration).