Skip to content

Commit 4a80ec3

Browse files
committed
add document on enabling https, both with manual and letsencrypt certificates
1 parent 83f3327 commit 4a80ec3

File tree

3 files changed

+150
-18
lines changed

3 files changed

+150
-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: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
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+
# need an http endpoint, not just https
75+
[entrypoints.http]
76+
address = ":80"
77+
78+
[certificateResolvers.letsencrypt.acme]
79+
80+
storage = "acme.json" # file where certificates are stored
81+
[certificateResolvers.letsencrypt.acme.httpChallenge]
82+
entryPoint = "http"
83+
```
84+
85+
And in your extra dynamic configuration, specify the domain(s) you want certificates for:
86+
87+
```toml
88+
# dynamic configuration
89+
[tls.stores.default.defaultGeneratedCert]
90+
resolver = "letsencrypt"
91+
[tls.stores.default.defaultGeneratedCert.domain]
92+
main = "hub.example.com"
93+
sans = [
94+
# if you are serving more than one domain
95+
"other.service.example.com",
96+
]
97+
```
98+
99+
If you are using JupyterHub-managed traefik (`c.TraefikProxy.should_start = True`),
100+
you can specify this same configuration via TraefikProxy's `extra_static_config` and `extra_dynamic_config`:
101+
102+
```python
103+
c.TraefikProxy.traefik_entrypoint = "https"
104+
c.TraefikProxy.extra_static_config = {
105+
"entryPoints": {
106+
"http": {
107+
"address": ":80"
108+
},
109+
"https": {
110+
"http": {
111+
"tls": {
112+
"options": "default"
113+
}
114+
}
115+
},
116+
},
117+
"certificateResolvers": {
118+
"letsencrypt": {
119+
"acme": {
120+
"email": "[email protected]",
121+
"storage": "acme.json",
122+
},
123+
"httpChallenge": {
124+
"entryPoint": "https"
125+
}
126+
}
127+
128+
}
129+
}
130+
131+
132+
c.TraefikProxy.extra_dynamic_config = {
133+
"tls": {
134+
"stores": {
135+
"default": {
136+
"defaultGeneratedCert": {
137+
"resolver": "letsencrypt",
138+
"domain": {
139+
"main": "hub.example.com",
140+
}
141+
}
142+
}
143+
}
144+
},
145+
}
146+
```

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)