Skip to content
This repository has been archived by the owner on Nov 16, 2022. It is now read-only.

Commit

Permalink
Merge pull request #1005 from gratipay/certbot
Browse files Browse the repository at this point in the history
Put together a new TLS workflow
  • Loading branch information
chadwhitacre authored Feb 24, 2017
2 parents 37d5d60 + 8a6f712 commit 8b322da
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 73 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ local.env
*.egg-info
www/appendices/disclosures.json
tests/.cache
certs/
8 changes: 8 additions & 0 deletions certs/assets.gratipay.com.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
config-dir = tmp
work-dir = tmp
logs-dir = tmp
authenticator = manual
preferred-challenges = dns
email = support@gratipay.com
domains = assets.gratipay.com, downloads.gratipay.com
rsa-key-size = 4096
8 changes: 8 additions & 0 deletions certs/gratipay.com.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
config-dir = tmp
work-dir = tmp
logs-dir = tmp
authenticator = manual
preferred-challenges = http
email = support@gratipay.com
domains = gratipay.com, gittip.co, www.gittip.co, gittip.com, www.gittip.com, gratipay.co, www.gratipay.co, www.gratipay.com, gratipay.net, www.gratipay.net, gratipay.org, www.gratipay.org
rsa-key-size = 4096
109 changes: 109 additions & 0 deletions www/howto/install-a-tls-certificate.spt
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import random
import string

nav_title="Install a TLS Certificate"
[---]
pool = string.lowercase + string.digits
random_subdomain = ''.join([random.choice(pool) for i in range(8)])
[---] text/html

Our certificate vendor is [Let's Encrypt](https://letsencrypt.org/), and the
way we get certificates from them is via their
[certbot](https://certbot.eff.org/docs/using.html#manual) command-line tool. We
have several domains to secure, plus aliases, and the way to verify ownership
and install the certificate vary for each. They are described below.

Let's Encrypt enforces frequent cert rolling via 90-day expirations. Once we
hit our first expiration cycle and sort out how to renew, we should update
these docs. Eventually we can explore further automation.


## `gratipay.com`

Install `certbot` locally, then run it in the `certs` directory of an Inside
Gratipay repo checkout, with the provided [configuration
file](https://github.com/gratipay/inside.gratipay.com/tree/master/certs/conf/):

```
git clone git@github.com:gratipay/inside.gratipay.com.git
cd certs
certbot certonly -c gratipay.com.ini
```

You'll have to agree to having your IP address publicly logged, and then you'll
be prompted to verify ownership of the domains via [`http-01`
challenges](https://tools.ietf.org/html/draft-ietf-acme-acme-03#section-7.2).
For that, visit the [ACME
Challenger](https://gratipay.com/.well-known/acme-challenge/) (you'll have to
login as an admin to use it). Go through the challenge cycle for `gratipay.com`
and for each alias (there are a bunch, including `www.*` variants), by
appending the token to the above link, and then entering the authorization
response in the form you find there.

Once you have the cert, install it [at
Heroku](https://devcenter.heroku.com/articles/ssl-endpoint#provision-the-add-on):

```
cd tmp/live/gratipay.com/
heroku certs:update --app gratipay fullchain.pem privkey.pem
```

Once you're done, `rm -rf tmp` to clear out sensitive files from your laptop.


## `{assets,downlaods}.gratipay.com`

Our `assets.gratipay.com` CDN uses `gratipay.com/assets` as its origin server,
and we have a read-only ACME Challenger
[endpoint](https://assets.gratipay.com/.well-known/acme-challenge/deadbeef)
under there. Therefore, the process to verify the domain is just like for
`gratipay.com`: create the challenge response in the normal [ACME
challenger](https://gratipay.com/.well-known/acme-challenge/), and Let's
Encrypt should find what it needs in the right place.

However, we use the same cert for `downloads.*` as for `assets.*`, since both
are hosted at MaxCDN. But since `downloads` is a PUSH zone, you have to
(manually) upload a file via FTP in order to verify the domain. Here's how to
[reset](https://www.maxcdn.com/one/tutorial/reset-push-ftp-password/) the ftp
password. Aaaaaaaaaand there's no way to serve a hidden directory, so you have
to use [DNS](https://tools.ietf.org/html/draft-ietf-acme-acme-03#section-7.4)
verification after all, so you may as well use it for `assets.*`, too (how do
we write a config file that splits the authenticators by domain?). Sorry.
😞

(P.S. The reason we don't just do *all* verification via DNS is because that's
harder to automate … though I guess DNSimple does have [an
API](https://developer.dnsimple.com/v2/zones/records/#create). Hmm …)

To install the cert, login to [MaxCDN](https://www.maxcdn.com/) (creds are in
LastPass). Go to Account > SSL to add the new certificate, then navigate to
EdgeSSL > SNI for each zone, and select the new cert. After installing for both
zones, go back to Account > SSL and delete the old cert.

Delete the TXT records from DNS.


## `grtp.co`

```
ssh root@grtp.co
cd certs/
```

You should find a
[`certbot-auto`](https://certbot.eff.org/docs/install.html#certbot-auto)
executable there, along with a `certbot.ini` configuration file, some logfiles,
etc. I *think* all you need to do is `./certbot-auto renew`, but since we're
still in our first cert cycle with Let's Encrypt, it's hard to know for sure.
😌

To verify domains, I ran `./certbot-auto certonly -c certbot.ini`, creating
(and subsequently cleaning up) files under:

```
~grtp.co/production/www/.well-known/acme-challenge/
```

The cert and key are symlinked into `/etc/nginx/certs/`, so you shouldn't need
to do anything other than `/etc/init.d/nginx reload` once the cert/key are
updated.
73 changes: 0 additions & 73 deletions www/howto/install-an-ssl-certificate.spt

This file was deleted.

0 comments on commit 8b322da

Please sign in to comment.