Skip to content

Commit 86ed23b

Browse files
authored
Merge pull request #204 from minrk/doc-ssl
add document on enabling https
2 parents 83f3327 + cae4d62 commit 86ed23b

File tree

3 files changed

+155
-18
lines changed

3 files changed

+155
-18
lines changed

docs/source/file.md

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -116,29 +116,14 @@ If TraefikFileProviderProxy is used as an externally managed service, then make
116116
# c.TraefikFileProviderProxy.traefik_api_validate_cert = True
117117

118118
# jupyterhub will configure traefik for itself, using this Host name
119-
# (and optional path) on the router rule:-
120-
c.JupyterHub.bind_url = 'https://hub.contoso.com'
119+
# (and optional path) on the router rule:
120+
c.JupyterHub.bind_url = 'http://hub.contoso.com'
121121

122122
# jupyterhub will also configure traefik's 'service' url, so this needs
123123
# to be accessible from traefik. By default, jupyterhub will bind to
124124
# 'localhost', but this will bind jupyterhub to its hostname
125+
# (only necessary when traefik is in a different machine or container)
125126
c.JupyterHub.hub_bind_url = 'http://:8000'
126-
127-
# jupyterhub will only allow path-based routing by default. To stop
128-
# jupyterhub from serving all requests, i.e. it will add a global router
129-
# rule of just PathPrefix(`/`) by default, we must configure jupyterhub as
130-
# a subdomain host.
131-
c.JupyterHub.subdomain_host = "https://hub.contoso.com"
132-
133-
# traefik can automatically request certificates from an ACME CA.
134-
# JupyterHub needs to know the name of traefik's certificateResolver
135-
c.TraefikFileProviderProxy.traefik_cert_resolver = "leresolver"
136-
137-
# For jupyterhub to let traefik manage certificates, 'ssl_cert' needs a
138-
# value. (This gets around a validate rule on 'proxy.bind_url', which
139-
# forces the protocol to 'http' unless there is a value in ssl_cert).
140-
c.JupyterHub.ssl_cert = 'externally managed'
141-
142127
```
143128

144129
3. Ensure **traefik.toml** / **traefik.yaml**

docs/source/https.md

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
# Enabling HTTPS with TraefikProxy
2+
3+
When running JupyterHub, you almost always want to use TLS (HTTPS).
4+
Traefik has a few ways to do that.
5+
The first tricky bit is that traefik separates [dynamic configuration from static configuration](https://doc.traefik.io/traefik/getting-started/configuration-overview/#the-dynamic-configuration),
6+
and some configuration needs to go in static, while some goes in dynamic.
7+
8+
## Static configuration
9+
10+
If you are using externally-managed traefik (`c.TraefikProxy.should_start = False`),
11+
you must write the _static_ configuration file yourself.
12+
The only static configuration required by juptyerhub-traefik-proxy
13+
is the creation of the entrypoints for the api and jupyterhub itself:
14+
15+
```toml
16+
# static configuration
17+
18+
# enable API
19+
[api]
20+
21+
[entryPoints.auth_api]
22+
address = "localhost:8099" # should match c.TraefikProxy.traefik_api_url
23+
24+
[entrypoints.https]
25+
address = ":443"
26+
27+
[entrypoints.https.http.tls]
28+
options = "default"
29+
```
30+
31+
jupyterhub-traefik-proxy can take care of the rest because it will apply its dynamic configuration when JupyterHub starts.
32+
33+
## Manual SSL
34+
35+
Configuring SSL with your own certificates works the same with traefik proxy as any other JupyterHub proxy implementation:
36+
37+
```python
38+
c.JupyterHub.ssl_cert = "/path/to/ssl.cert"
39+
c.JupyterHub.ssl_key = "/path/to/ssl.key"
40+
```
41+
42+
This will set the traefik **dynamic configuration**:
43+
44+
```toml
45+
# dynamic configuration
46+
[tls.stores.default.defaultCertificate]
47+
certFile = "path/to/cert.crt"
48+
keyFile = "path/to/cert.key"
49+
```
50+
51+
If you don't tell jupyterhub about these files,
52+
you will need to set this configuration yourself in **dynamic configuration**
53+
(Traefik ignores TLS configuration in the "static" configuration file).
54+
Passing the certificates via JupyterHub configuration assumes the `options = "default"` static configuration:
55+
56+
```toml
57+
# static configuration
58+
[entrypoints.https.http.tls]
59+
options = "default"
60+
```
61+
62+
If you use your own static and dynamic configuration files, you don't have to use the 'default' TLS options or tell jupyterhub anything about your TLS configuration.
63+
64+
## Let's Encrypt
65+
66+
Traefik supports using Let's Encrypt for automatically issuing and renewing certificates.
67+
It's great!
68+
69+
To configure traefik to use let's encrypt, first we need to register a [certificate resolver](https://doc.traefik.io/traefik/https/acme/) in static configuration:
70+
71+
```toml
72+
# static configuration
73+
74+
# redirect all http requests to https
75+
[entrypoints.httponly]
76+
address = ":80"
77+
[entryPoints.httponly.http.redirections.entryPoint]
78+
to = "https"
79+
scheme = "https"
80+
81+
# configure
82+
[certificatesResolvers.letsencrypt.acme]
83+
84+
storage = "acme.json" # file where certificates are stored
85+
# use the staging server to test your deployment
86+
# uncomment this when you are ready for production
87+
caServer = "https://acme-staging-v02.api.letsencrypt.org/directory"
88+
89+
# tlsChallenge means you don't need an http endpoint
90+
[certificatesResolvers.letsencrypt.acme.tlsChallenge]
91+
```
92+
93+
And in your extra dynamic configuration, specify the domain(s) you want certificates for:
94+
95+
```toml
96+
# dynamic configuration
97+
[tls.stores.default.defaultGeneratedCert]
98+
resolver = "letsencrypt"
99+
[tls.stores.default.defaultGeneratedCert.domain]
100+
main = "hub.example.com"
101+
sans = [
102+
# if you are serving more than one domain
103+
"other.service.example.com",
104+
]
105+
```
106+
107+
If you are using JupyterHub-managed traefik (`c.TraefikProxy.should_start = True`),
108+
you can specify this same configuration via TraefikProxy's `extra_static_config` and `extra_dynamic_config`:
109+
110+
```python
111+
c.TraefikProxy.traefik_entrypoint = "https"
112+
c.TraefikProxy.extra_static_config = {
113+
"entryPoints": {
114+
"http": {
115+
"address": ":80"
116+
},
117+
"https": {
118+
"http": {
119+
"tls": {
120+
"options": "default"
121+
},
122+
},
123+
},
124+
},
125+
"certificatesResolvers": {
126+
"letsencrypt": {
127+
"acme": {
128+
"email": "[email protected]",
129+
"storage": "acme.json",
130+
},
131+
"tlsChallenge": {},
132+
},
133+
},
134+
}
135+
136+
137+
c.TraefikProxy.extra_dynamic_config = {
138+
"tls": {
139+
"stores": {
140+
"default": {
141+
"defaultGeneratedCert": {
142+
"resolver": "letsencrypt",
143+
"domain": {
144+
"main": "hub.example.com",
145+
},
146+
},
147+
},
148+
},
149+
},
150+
}
151+
```

docs/source/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ install
3232
```{toctree}
3333
:maxdepth: 1
3434
35+
https
3536
file
3637
etcd
3738
consul

0 commit comments

Comments
 (0)