Skip to content

HTTPS Production

Steve Huff edited this page Oct 16, 2016 · 1 revision

TLS certificates for production deployments

This is a sketchy manual process which must be done every 6 months. At some point this should probably be automated.

To generate a new TLS certificate for a production deployment:

Make sure DNS for your desired hostname resolves properly.

# host members.worldcon.fi
members.worldcon.fi is an alias for nginx.api.3c3a85c0.svc.dockerapp.io.
nginx.api.3c3a85c0.svc.dockerapp.io has address 185.26.51.169

SSH to the production server and become root.

# cd /opt/data/nginx; mkdir -p certbot{/var/lib/letsencrypt,/etc/letsencrypt}`
# docker run -it --rm --name certbot \
    -v "$(pwd)/certbot/etc/letsencrypt:/etc/letsencrypt" \
    -v "$(pwd)/certbot/var/lib/letsencrypt:/var/lib/letsencrypt" \
    quay.io/letsencrypt/letsencrypt:latest certonly --manual

Do the manual certbot procedure. Enter [email protected] as the contact email address, enter the desired hostname when prompted, agree to having the host IP logged.

At one point you will have to create a file at a URL that looks something like this:

http://members.worldcon.fi/.well-known/acme-challenge/<long ugly string>

The file will need to contain one line of text, which will also be provided to you by certbot; use echo or vim or whatever text editor you want to create the file in /opt/data/nginx/acme-challenge on the production server.

Confirm that you can read the file FROM AN EXTERNAL HOST (i.e. your laptop) before proceeding:

$ curl -v http://members.worldcon.fi/.well-known/acme-challenge/<long ugly string>
*   Trying 185.26.51.169...
* Connected to members.worldcon.fi (185.26.51.169) port 80 (#0)
> GET /.well-known/acme-challenge/<long ugly string> HTTP/1.1
> Host: members.worldcon.fi
> User-Agent: Mozilla/4.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.10.1
< Date: Sun, 16 Oct 2016 17:00:03 GMT
< Content-Type: application/octet-stream
< Content-Length: 88
< Last-Modified: Sun, 16 Oct 2016 16:59:42 GMT
< Connection: keep-alive
< ETag: "5803b1fe-58"
< Accept-Ranges: bytes
<
<even longer ugly string>
* Connection #0 to host members.worldcon.fi left intact

Confirm that your cert and key have been written to local disk:

# ls -l certbot/etc/letsencrypt/live/members.worldcon.fi/
total 0
lrwxrwxrwx 1 root root 43 Oct 16 20:00 cert.pem -> ../../archive/members.worldcon.fi/cert1.pem
lrwxrwxrwx 1 root root 44 Oct 16 20:00 chain.pem -> ../../archive/members.worldcon.fi/chain1.pem
lrwxrwxrwx 1 root root 48 Oct 16 20:00 fullchain.pem -> ../../archive/members.worldcon.fi/fullchain1.pem
lrwxrwxrwx 1 root root 46 Oct 16 20:00 privkey.pem -> ../../archive/members.worldcon.fi/privkey1.pem

Copy the cert and key into the mapped Docker volume:

# cp certbot/etc/letsencrypt/live/members.worldcon.fi/fullchain.pem ssl/server.cert
# cp certbot/etc/letsencrypt/live/members.worldcon.fi/privkey.pem ssl/server.key

Redeploy the nginx service from the Docker Cloud control panel.

Confirm that the certificate is valid:

$ curl -v https://members.worldcon.fi
* Rebuilt URL to: https://members.worldcon.fi/
*   Trying 185.26.51.169...
* Connected to members.worldcon.fi (185.26.51.169) port 443 (#0)
* TLS 1.2 connection using TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
* Server certificate: members.worldcon.fi
* Server certificate: Let's Encrypt Authority X3
* Server certificate: DST Root CA X3
> GET / HTTP/1.1
> Host: members.worldcon.fi
> User-Agent: Mozilla/4.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.10.1
< Date: Sun, 16 Oct 2016 17:14:44 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 208
< Last-Modified: Sun, 16 Oct 2016 16:52:16 GMT
< Connection: keep-alive
< ETag: "5803b040-d0"
< Strict-Transport-Security: max-age=15768000
< Accept-Ranges: bytes
<
<!doctype html>
...
Clone this wiki locally