Skip to content

Commit 3f6d5b7

Browse files
authored
Adding production docs (Netflix#658)
* Adding production docs
1 parent f95efc7 commit 3f6d5b7

1 file changed

Lines changed: 219 additions & 5 deletions

File tree

‎docs/installation.md‎

Lines changed: 219 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ Dispatch relies on multiple services to work, which are all orchestrated by `Doc
44

55
### Requirements
66

7-
* [Docker](https://www.docker.com/) 17.05.0+
8-
* [Docker Compose](https://docs.docker.com/compose/) 1.19.0+
9-
* A dedicated \(sub\)domain to host Dispatch on \(for example, dispatch.yourcompany.com\).
10-
* At least 2400MB memory
11-
* 2 CPU Cores
7+
- [Docker](https://www.docker.com/) 17.05.0+
8+
- [Docker Compose](https://docs.docker.com/compose/) 1.19.0+
9+
- A dedicated \(sub\)domain to host Dispatch on \(for example, dispatch.yourcompany.com\).
10+
- At least 2400MB memory
11+
- 2 CPU Cores
1212

1313
## Installing Dispatch Server
1414

@@ -36,3 +36,217 @@ To start, run the install script:
3636
./install.sh
3737
```
3838

39+
## Going to Production
40+
41+
Before you deploy Dispatch to production there are a few considerations and steps that should taken.
42+
43+
### Basics
44+
45+
Because of the sensitivity of the information stored and maintained by Dispatch it is important that you follow standard host hardening practices:
46+
47+
- Run Dispatch with a limited user
48+
- Disabled any unneeded services
49+
- Enable remote logging
50+
- Restrict access to host
51+
52+
### Credential Management
53+
54+
Dispatch plugins require API tokens that are used to communicate with third party resources. These are typically stored in either the an environment variable or in the Dispatch `.env` file.
55+
56+
By default these strings are in plain text, but Dispatch does provide hooks that allow for these credentials to be decrypted on server start. See the [Secret Provider](configuration/app.md#general) configuration option.
57+
58+
### Authentication
59+
60+
To get going quickly, Dispatch provides a "Basic Authentication" provider that controls access via a username and password combination. By default, this provider allows for **open registration**. Meaning that anyone will be able to create a Dispatch account if they have network access to your server.
61+
62+
For a more robust authentication, Dispatch provides a PKCE authentication method that can be used to integrate with existing and more robust SSO solutions. See the [Authentication Provider](configuration/app.md#authentication)
63+
64+
### TLS/SSL
65+
66+
#### Nginx
67+
68+
Nginx is a very popular choice to serve a Python project:
69+
70+
- It’s fast.
71+
- It’s lightweight.
72+
- Configuration files are simple.
73+
74+
Nginx doesn’t run any Python process, it only serves requests from outside to the Python server.
75+
76+
Therefore, there are two steps:
77+
78+
- Run the Python process.
79+
- Run Nginx.
80+
81+
You will benefit from having:
82+
83+
- The possibility to have several projects listening to the port 80;
84+
- Your web site processes won’t run with admin rights, even if –user doesn’t work on your OS;
85+
-The ability to manage a Python process without touching Nginx or the other processes. It’s very handy for updates.
86+
87+
You must create a Nginx configuration file for Dispatch. On GNU/Linux, they usually go into /etc/nginx/conf.d/. Name it dispatch.conf.
88+
89+
proxy_pass just passes the external request to the Python process. The port must match the one used by the Dispatch process of course.
90+
91+
You can make some adjustments to get a better user experience:
92+
93+
server_tokens off;
94+
add_header X-Frame-Options DENY;
95+
add_header X-Content-Type-Options nosniff;
96+
add_header X-XSS-Protection "1; mode=block";
97+
98+
server {
99+
listen 80;
100+
return 301 https://$host$request_uri;
101+
}
102+
103+
server {
104+
listen 443;
105+
access_log /var/log/nginx/log/dispatch.access.log;
106+
error_log /var/log/nginx/log/dispatch.error.log;
107+
108+
location /api {
109+
proxy_pass http://127.0.0.1:8000;
110+
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
111+
proxy_redirect off;
112+
proxy_buffering off;
113+
proxy_set_header Host $host;
114+
proxy_set_header X-Real-IP $remote_addr;
115+
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
116+
}
117+
118+
location / {
119+
root /path/to/dispatch/static/dist;
120+
include mime.types;
121+
index index.html;
122+
}
123+
124+
}
125+
This makes Nginx serve the favicon and static files which it is much better at than python.
126+
127+
It is highly recommended that you deploy TLS when deploying Dispatch. This may be obvious given Dispatch’s purpose but the sensitive nature of Dispatch and what it controls makes this essential. This is a sample config for Dispatch that also terminates TLS:
128+
129+
{% hint style="info" %}
130+
Some paths will have to be adjusted based on where you have choose to install Dispatch.
131+
{% endhint %}
132+
133+
```
134+
server_tokens off;
135+
add_header X-Frame-Options DENY;
136+
add_header X-Content-Type-Options nosniff;
137+
add_header X-XSS-Protection "1; mode=block";
138+
139+
server {
140+
listen 80;
141+
return 301 https://$host$request_uri;
142+
}
143+
144+
server {
145+
listen 443;
146+
access_log /var/log/nginx/log/dispatch.access.log;
147+
error_log /var/log/nginx/log/dispatch.error.log;
148+
149+
# certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
150+
151+
ssl_certificate /path/to/signed_cert_plus_intermediates;
152+
ssl_certificate_key /path/to/private_key;
153+
ssl_session_timeout 1d;
154+
ssl_session_cache shared:SSL:50m;
155+
156+
# Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
157+
158+
ssl_dhparam /path/to/dhparam.pem;
159+
160+
# modern configuration. tweak to your needs.
161+
162+
ssl_protocols TLSv1.1 TLSv1.2;
163+
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK';
164+
ssl_prefer_server_ciphers on;
165+
166+
# HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
167+
168+
add_header Strict-Transport-Security max-age=15768000;
169+
170+
# OCSP Stapling ---
171+
172+
# fetch OCSP records from URL in ssl_certificate and cache them
173+
174+
ssl_stapling on;
175+
ssl_stapling_verify on;
176+
177+
## verify chain of trust of OCSP response using Root CA and Intermediate certs
178+
179+
ssl_trusted_certificate /path/to/root_CA_cert_plus_intermediates;
180+
181+
resolver <IP DNS resolver>;
182+
183+
location /api {
184+
proxy_pass http://127.0.0.1:8000;
185+
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
186+
proxy_redirect off;
187+
proxy_buffering off;
188+
proxy_set_header Host $host;
189+
proxy_set_header X-Real-IP $remote_addr;
190+
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
191+
}
192+
193+
location / {
194+
root /path/to/dispatch/static/dist;
195+
include mime.types;
196+
index index.html;
197+
}
198+
199+
}
200+
```
201+
202+
Apache
203+
An example apache config:
204+
205+
```
206+
<VirtualHost \*:443>
207+
...
208+
SSLEngine on
209+
SSLCertificateFile /path/to/signed_certificate
210+
SSLCertificateChainFile /path/to/intermediate_certificate
211+
SSLCertificateKeyFile /path/to/private/key
212+
SSLCACertificateFile /path/to/all_ca_certs
213+
214+
# intermediate configuration, tweak to your needs
215+
SSLProtocol all -SSLv2 -SSLv3
216+
SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
217+
SSLHonorCipherOrder on
218+
219+
# HSTS (mod_headers is required) (15768000 seconds = 6 months)
220+
Header always set Strict-Transport-Security "max-age=15768000"
221+
...
222+
223+
# Set the dispatch DocumentRoot to static/dist
224+
225+
DocumentRoot /www/dispatch/dispatch/static/dist
226+
227+
# Uncomment to force http 1.0 connections to proxy
228+
229+
# SetEnv force-proxy-request-1.0 1
230+
231+
#Don't keep proxy connections alive
232+
SetEnv proxy-nokeepalive 1
233+
234+
# Only need to do reverse proxy
235+
236+
ProxyRequests Off
237+
238+
# Proxy requests to the api to the dispatch service (and sanitize redirects from it)
239+
240+
ProxyPass "/api" "http://127.0.0.1:8000/api"
241+
ProxyPassReverse "/api" "http://127.0.0.1:8000/api"
242+
243+
</VirtualHost>
244+
```
245+
246+
{% hint style="info" %}
247+
This is a rather incomplete apache config for running Dispatch (needs mod_wsgi etc.), if you have a working apache config please let us know!
248+
{% endhint %}
249+
250+
Also included in the configurations above are several best practices when it comes to deploying TLS. Things like enabling HSTS, disabling vulnerable ciphers are all good ideas when it comes to deploying Dispatch into a production environment.
251+
252+
For more SSL configuration options see: [Mozilla SSL Configuration Generator](https://mozilla.github.io/server-side-tls/ssl-config-generator/)

0 commit comments

Comments
 (0)