Merge branch 'master' into named_servers

This commit is contained in:
Min RK
2017-07-25 16:56:16 +02:00
committed by GitHub
5 changed files with 124 additions and 81 deletions

View File

@@ -99,7 +99,7 @@ more configuration of the system.
## Configuration
The [Getting Started](docs/source/getting-started.md) section of the
The [Getting Started](http://jupyterhub.readthedocs.io/en/latest/getting-started.html) section of the
documentation explains the common steps in setting up JupyterHub.
The [**JupyterHub tutorial**](https://github.com/jupyterhub/jupyterhub-tutorial)

View File

@@ -1,45 +1,72 @@
# Configuration Basics
The [getting started document](docs/source/getting-started.md) contains
general information about configuring a JupyterHub deployment and the
[configuration reference](docs/source/configuration-guide.md) provides more
comprehensive detail.
The section contains basic information about configuring settings for a JupyterHub
deployment. The [configuration reference](./configuration-guide.html)
provides additional detail.
## JupyterHub configuration
This section will help you learn how to:
Configuration parameters may be set by:
- a configuration file `jupyterhub_config.py`, or
- as options from the command line.
- generate a default configuration file, `jupyterhub_config.py`
- start with a specific configuration file
- configure JupyterHub using command line options
- find information and examples for some common deployments
### Generate a default config file
## Generate a default config file
On startup, JupyterHub will look by default for a configuration file named
`jupyterhub_config.py` in the current working directory.
On startup, JupyterHub will look by default for a configuration file,
`jupyterhub_config.py`, in the current working directory.
To generate a default config file `jupyterhub_config.py`:
To generate a default config file, `jupyterhub_config.py`:
```bash
jupyterhub --generate-config
```
This default `jupyterhub_config.py` file contains comments and guidance for all
configuration variables and their default values.
configuration variables and their default values. We recommend storing
configuration files in the standard UNIX filesystem location, i.e.
`/etc/jupyterhub`.
### Configure using command line options
## Start with a specific config file
You can load a specific config file and start JupyterHub using:
```bash
jupyterhub -f /path/to/jupyterhub_config.py
```
If you have stored your configuration file in the recommended UNIX filesystem
location, `/etc/jupyterhub`, the following command will start JupyterHub using
the configuration file:
```bash
jupyterhub -f /etc/jupyterhub/jupyterhub_config.py
```
The IPython documentation provides additional information on the
[config system](http://ipython.readthedocs.io/en/stable/development/config.html)
that Jupyter uses.
## Configure using command line options
To display all command line options that are available for configuration:
```bash
jupyterhub --help-all
```
Configuration using the command line options is done when launching JupyterHub.
For example, to start JupyterHub on ``10.0.1.2:443`` with **https**, you
For example, to start JupyterHub on ``10.0.1.2:443`` with https, you
would enter:
```bash
jupyterhub --ip 10.0.1.2 --port 443 --ssl-key my_ssl.key --ssl-cert my_ssl.cert
```
All configurable options are technically configurable on the command-line,
even if some are really inconvenient to type. Just replace the desired option,
`c.Class.trait`, with `--Class.trait`. For example, to configure the
All configurable options may technically be set on the command-line,
though some are inconvenient to type. To set a particular configuration
parameter, `c.Class.trait`, you would use the command line option,
`--Class.trait`, when starting JupyterHub. For example, to configure the
`c.Spawner.notebook_dir` trait from the command-line, use the
`--Spawner.notebook_dir` option:
@@ -47,23 +74,14 @@ even if some are really inconvenient to type. Just replace the desired option,
jupyterhub --Spawner.notebook_dir='~/assignments'
```
### Load a specific config file
## Configure for various deployment environments
You can load a specific config file with:
```bash
jupyterhub -f /path/to/jupyterhub_config.py
```
See also: [general docs](http://ipython.org/ipython-doc/dev/development/config.html)
on the config system Jupyter uses.
### Configuration for different deployment environments
The default authentication and process spawning mechanisms can be replaced,
which allows plugging into a variety of authentication methods or process
control and deployment environments. Some examples, meant as illustration and
testing of this concept, are:
The default authentication and process spawning mechanisms can be replaced, and
specific [authenticators](./authenticators-users-basics.html) and
[spawners](./spawners-basics.html) can be set in the configuration file.
This enables JupyterHub to be used with a variety of authentication methods or
process control and deployment environments. [Some examples](./config-examples.html),
meant as illustration, are:
- Using GitHub OAuth instead of PAM with [OAuthenticator](https://github.com/jupyterhub/oauthenticator)
- Spawning single-user servers with Docker, using the [DockerSpawner](https://github.com/jupyterhub/dockerspawner)

View File

@@ -1,30 +1,30 @@
# Configuration examples
This section provides configuration files and tips for the following
configurations:
This section provides examples, including configuration files and tips, for the
following configurations:
- Example with GitHub OAuth
- Example with nginx reverse proxy
- JupyterHub deployment on AWS with NGINX
- Using GitHub OAuth
- Using nginx reverse proxy
## Using GitHub OAuth
## Example with GitHub OAuth
In this example, we show a configuration file for a fairly standard JupyterHub
deployment with the following assumptions:
In the following example, we show a configuration files for a fairly standard JupyterHub deployment with the following assumptions:
* JupyterHub is running on a single cloud server
* Running JupyterHub on a single cloud server
* Using SSL on the standard HTTPS port 443
* You want to use GitHub OAuth (using oauthenticator) for login
* You need the users to exist locally on the server
* You want users' notebooks to be served from `~/assignments` to allow users to browse for notebooks within
other users home directories
* You want the landing page for each user to be a Welcome.ipynb notebook in their assignments directory.
* Using GitHub OAuth (using oauthenticator) for login
* Users exist locally on the server
* Users' notebooks to be served from `~/assignments` to allow users to browse
for notebooks within other users' home directories
* You want the landing page for each user to be a `Welcome.ipynb` notebook in
their assignments directory.
* All runtime files are put into `/srv/jupyterhub` and log files in `/var/log`.
Let's start out with `jupyterhub_config.py`:
The `jupyterhub_config.py` file would have these settings:
```python
# jupyterhub_config.py
# jupyterhub_config.py file
c = get_config()
import os
@@ -35,7 +35,6 @@ ssl_dir = pjoin(runtime_dir, 'ssl')
if not os.path.exists(ssl_dir):
os.makedirs(ssl_dir)
# Allows multiple single-server per user
c.JupyterHub.allow_named_servers = True
@@ -54,9 +53,9 @@ c.JupyterHub.db_url = pjoin(runtime_dir, 'jupyterhub.sqlite')
c.JupyterHub.extra_log_file = '/var/log/jupyterhub.log'
# use GitHub OAuthenticator for local users
c.JupyterHub.authenticator_class = 'oauthenticator.LocalGitHubOAuthenticator'
c.GitHubOAuthenticator.oauth_callback_url = os.environ['OAUTH_CALLBACK_URL']
# create system users that don't exist yet
c.LocalAuthenticator.create_system_users = True
@@ -72,34 +71,42 @@ c.Spawner.notebook_dir = '~/assignments'
c.Spawner.args = ['--NotebookApp.default_url=/notebooks/Welcome.ipynb']
```
Using the GitHub Authenticator [requires a few additional env variables][oauth-setup],
which we will need to set when we launch the server:
Using the GitHub Authenticator requires a few additional
environment variable to be set prior to launching JupyterHub:
```bash
export GITHUB_CLIENT_ID=github_id
export GITHUB_CLIENT_SECRET=github_secret
export OAUTH_CALLBACK_URL=https://example.com/hub/oauth_callback
export CONFIGPROXY_AUTH_TOKEN=super-secret
jupyterhub -f /path/to/aboveconfig.py
jupyterhub -f /etc/jupyterhub/jupyterhub_config.py
```
## Example with nginx reverse proxy
## Using nginx reverse proxy
In the following example, we show configuration files for a JupyterHub server running locally on port `8000` but accessible from the outside on the standard SSL port `443`. This could be useful if the JupyterHub server machine is also hosting other domains or content on `443`. The goal here is to have the following be true:
In the following example, we show configuration files for a JupyterHub server
running locally on port `8000` but accessible from the outside on the standard
SSL port `443`. This could be useful if the JupyterHub server machine is also
hosting other domains or content on `443`. The goal in this example is to
satisfy the following:
* JupyterHub is running on a server, accessed *only* via `HUB.DOMAIN.TLD:443`
* On the same machine, `NO_HUB.DOMAIN.TLD` strictly serves different content, also on port `443`
* `nginx` is used to manage the web servers / reverse proxy (which means that only nginx will be able to bind two servers to `443`)
* After testing, the server in question should be able to score an A+ on the Qualys SSL Labs [SSL Server Test](https://www.ssllabs.com/ssltest/)
* On the same machine, `NO_HUB.DOMAIN.TLD` strictly serves different content,
also on port `443`
* `nginx` is used to manage the web servers / reverse proxy (which means that
only nginx will be able to bind two servers to `443`)
* After testing, the server in question should be able to score an A+ on the
Qualys SSL Labs [SSL Server Test](https://www.ssllabs.com/ssltest/)
Let's start out with `jupyterhub_config.py`:
Let's start out with needed JupyterHub configuration in `jupyterhub_config.py`:
```python
# Force the proxy to only listen to connections to 127.0.0.1
c.JupyterHub.ip = '127.0.0.1'
```
The `nginx` server config files are fairly standard fare except for the two `location` blocks within the `HUB.DOMAIN.TLD` config file:
The **`nginx` server config file** is fairly standard fare except for the two
`location` blocks within the `HUB.DOMAIN.TLD` config file:
```bash
# HTTP server to redirect all 80 traffic to SSL/HTTPS
@@ -162,7 +169,11 @@ server {
}
```
`nginx` will now be the front facing element of JupyterHub on `443` which means it is also free to bind other servers, like `NO_HUB.DOMAIN.TLD` to the same port on the same machine and network interface. In fact, one can simply use the same server blocks as above for `NO_HUB` and simply add line for the root directory of the site as well as the applicable location call:
`nginx` will now be the front facing element of JupyterHub on `443` which means
it is also free to bind other servers, like `NO_HUB.DOMAIN.TLD` to the same port
on the same machine and network interface. In fact, one can simply use the same
server blocks as above for `NO_HUB` and simply add line for the root directory
of the site as well as the applicable location call:
```bash
server {
@@ -195,4 +206,6 @@ server {
}
```
Now just restart `nginx`, restart the JupyterHub, and enjoy accessing https://HUB.DOMAIN.TLD while serving other content securely on https://NO_HUB.DOMAIN.TLD.
Now just restart `nginx`, restart the JupyterHub, and enjoy accessing
https://HUB.DOMAIN.TLD while serving other content securely on
https://NO_HUB.DOMAIN.TLD.

View File

@@ -247,7 +247,19 @@ class Hashed(object):
def token(self, token):
"""Store the hashed value and prefix for a token"""
self.prefix = token[:self.prefix_length]
self.hashed = hash_token(token, rounds=self.rounds, salt=self.salt_bytes, algorithm=self.algorithm)
if len(token) >= 32:
# Tokens are generally UUIDs, which have sufficient entropy on their own
# and don't need salt & hash rounds.
# ref: https://security.stackexchange.com/a/151262/155114
rounds = 1
salt_bytes = b''
else:
# users can still specify API tokens in a few ways,
# so trigger salt & hash rounds if they provide a short token
app_log.warning("Applying salt & hash rounds to %sB token" % len(token))
rounds = self.rounds
salt_bytes = self.salt_bytes
self.hashed = hash_token(token, rounds=rounds, salt=salt_bytes, algorithm=self.algorithm)
def match(self, token):
"""Is this my token?"""
@@ -394,7 +406,7 @@ class OAuthAccessToken(Hashed, Base):
# from Hashed
hashed = Column(Unicode(64))
prefix = Column(Unicode(16))
prefix = Column(Unicode(16), index=True)
def __repr__(self):
return "<{cls}('{prefix}...', user='{user}'>".format(

View File

@@ -373,7 +373,7 @@ class Spawner(LoggingConfigurable):
This can be set independent of any concrete spawner implementation.
Example:
Example::
from subprocess import check_call
def my_hook(spawner):