TLS Termination¶
The SampleDB container comes with a built-in, production ready CherryPy web server which serves SampleDB via HTTP on port 8000. This is great for local testing, but if you run SampleDB in production, you should use HTTPS instead.
The recommended way of doing this is to set up an nginx container as a so-called reverse proxy that will handle TLS termination. Clients will send requests to nginx using HTTPS and nginx will internally communicate to the SampleDB container using HTTP.
You may have existing infrastructure which you can integrate SampleDB into, this guide is merely an example in case you are starting on a completely fresh system.
Please follow general system administration best practices.
Requirements¶
To follow this guide and set up TLS termination, you will need:
a domain name that is mapped to your host
a TLS certificate, saved as
certificate.crt
the corresponding private key, saved as
certificate.key
Your facility is likely to already have a domain name, and you may be able to use one of its subdomains, e.g. sampledb.yourdomain.tld
. If so, there likely is an established certficate authority your facility uses. If not, consider using a certificate authority like https://letsencrypt.org/.
Docker network¶
The first step is to make sure the three containers run in their own Docker network, so that they can communicate with each other while port 8000 of the SampleDB container will only be reachable internally:
docker network create --driver=bridge --subnet=172.24.0.0/16 sampledb-network
Next, assign IP addresses to the individual containers. The rest of this guide assumes that you use:
container |
IP address |
---|---|
sampledb |
172.24.0.1 |
sampledb-postgres |
172.24.0.2 |
sampledb-nginx |
172.24.0.3 |
When creating the containers with docker run
, pass the network and IP address to docker, by using the option:
--network=sampledb-network --ip=<ip_address>
Also make sure to remove the -p 8000:8000
option from the SampleDB container.
nginx Configuration¶
You can then create a sampledb.conf
file for nginx:
upstream sampledb {
server 172.24.0.1:8000;
}
ssl_session_cache shared:ssl_session_cache:10m;
server {
listen 80;
server_name <domain_name>;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name <domain_name>;
ssl_certificate certificate.crt;
ssl_certificate_key certificate.key;
ssl_protocols TLSv1.2;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:!aNULL";
ssl_prefer_server_ciphers on;
ssl_dhparam dhparam.pem;
add_header Strict-Transport-Security max-age=63072000;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
client_max_body_size 64M;
location / {
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://sampledb;
}
}
Note the usage of <domain_name>
and fill in your domain name there.
dhparam.pem¶
This configuration file requires the existance of a file dhparam.pem
containing the parameters for the Diffie-Helmann key exchange. To generate this file, run:
openssl dhparam -out dhparam.pem 4096
This may take a very long time to run.
nginx Container¶
With these files in place, you can start the nginx container:
docker run \
-d \
-v `pwd`/certificate.crt:/etc/nginx/certificate.crt:ro \
-v `pwd`/certificate.key:/etc/nginx/certificate.key:ro \
-v `pwd`/dhparam.pem:/etc/nginx/dhparam.pem:ro \
-v `pwd`/sampledb.conf:/etc/nginx/conf.d/default.conf:ro \
--network=sampledb-network \
--ip=172.24.0.3 \
--restart=always \
--name sampledb-nginx \
-p 80:80 \
-p 443:443 \
nginx
You should now be able to access SampleDB using your domain name and HTTPS.