11 Commits

Author SHA1 Message Date
Jeremy Stanley
33c8b1ac4b Retry acme.sh cloning
Sometimes we observe failures to clone acme.sh from GitHub. Retry it
up to three times with a two-second delay between each try, in hopes
of failing these jobs less often.

While we're here, update the URL to a more current one which doesn't
need redirecting.

Change-Id: I5179c0482afcb407b7d28d4c3ce73d96d41c6493
2021-10-13 18:31:46 +00:00
Ian Wienand
547a4578bd letsencrypt : don't use staging in the gate
Currently we connect to the LE staging environment with acme.sh during
CI to get the DNS-01 tokens (but we never follow-through and actually
generate the certificate, as we have nowhere to publish the tokens).
We've known for a while that LE staging isn't really meant to be used
by CI like this, and recent instability has made the issue pronounced.

This modifies the driver script to generate fake tokens which work to
ensure all the DNS processing, etc. is happening correctly.

I have put this behind a flag so the letsencrypt job still does this
however.  I think it is worth this job actually calling acme.sh to
validate this path; this shouldn't be required too often.

Change-Id: I7c0b471a0661aa311aaa861fd2a0d47b07e45a72
2021-10-06 15:34:21 +11:00
Clark Boylan
3d5d2779d2 Be explicit about server used in acme.sh
Acme.sh is updating their defaults to use zerossl instead of
letsencrypt [0]. This has resulted in errors like:

  Can not resolve _eab_id

When our runs of acme.sh attempt to communicate with zerossl. While the
default change isn't supposed to happen until August 1 we hit it early
because we consume the dev branch of acme.sh.

We avoid this entirely by being explicit about the server to communicate
to in our acme.sh driver script. We explicitly set --server to
letsencrypt.

Note that a followup should likely update our use of --staging to set
--server letsencrypt_test as --staging enforces their defaults as well.

[0] https://github.com/acmesh-official/acme.sh/wiki/Change-default-CA-to-ZeroSSL

Change-Id: Ia6a8da80869f1c4ff3240712bcd320bfc6f29e93
2021-06-18 08:48:35 -07:00
Ian Wienand
ac11734cf9 ansible-lint : disable 503
This has got me a number of times; I think we can tell in review if a
task firing in response to a "changed" is best in a handler or not.

Remove existing noqa flags

Change-Id: I80ad631f978eeeb9903abe230a95f23f5709d20e
2020-03-06 09:57:00 +11:00
Ian Wienand
3aaf87ee6d letsencrypt: Register email with accounts
Currently we don't set a contact email with our accounts.  This is an
optional feature, but would be helpful for things like [1] where we
would be notified of certificates affected by bugs, etc.

Setup the email address in the acme.sh config which will apply with
any new accounts created.  To update all the existing hosts, we see if
the account email is added/modified in the config *and* if we have
existing account details; if so we need a manual update call.

For anyone who might be poking here, we also add a note on sharing an
account based on some broadly agreed upon discussion in IRC.

[1] https://community.letsencrypt.org/t/revoking-certain-certificates-on-march-4/114864

Change-Id: Ib4dc3e179010419a1b18f355d13b62c6cc4bc7e8
2020-03-05 12:25:56 +11:00
Ian Wienand
a44f5acdf3 letsencrypt: force renewal on certificate change
There is a bug, or misfeature, in acme.sh using dns manual mode where
it will not renew the certificate when new domains are added to an
existing certificate.  It appears to generate the TXT record requests
correctly, but then when we renew the certificate it thinks it is not
time and skips it.  This is filed upstream with [1] however we can
work around it, and generally be better anyway.

For each letsencrypt host, during certificate request we build up the
"acme_txt_required" key which is a list of TXT record tuples.
Currently we keep the challenge domain in the first entry, which is
not useful (all our hosts have the same challenge domain,
amce.opendev.org).  Modify this to be the certificate key from the
host config.  To be clear; when a host has

letsencrypt_certs:
  hostname-cert-main:
    hostname.opendev.org
    altname.opendev.org
  hostname-cert-secondary:
    secondary.opendev.org
    secondaryalt.opendev.org

acme_txt_required when renewing all certs will end up looking like:

 [
  (hostname-cert-main, <txt1>), (hostname-cert-main, <txt2>),
  (hostname-cert-secondary, <txt3>), (hostname-cert-secondary, <txt3>>)
 ]

In the certificate creation path, we walk "acme_txt_required" and take
the unique 0-value entries; this gives us the list of keys in
"letsencrypt_certs" which were actually updated.

We can then force renewal for these certs, because we know they
changed in some way that requires reissuing them (within renewal time,
or new domains).

This isn't just a work-around, it is generically better too.
Previously if any cert on host required an update, we would try to
update them all.  This would be a no-op; acme.sh would just skip doing
anything; but now we don't even have to call into the renewal if we
know nothing has changed.

[1] https://github.com/acmesh-official/acme.sh/issues/2763

Change-Id: I1e82c64217d46d7e1acc0111dff4db2f0062c42a
2020-02-28 11:49:06 +11:00
Ian Wienand
17e31f907b Update letsencrypt_gid documentation
Added with Ie32124cd617e9986602301f230e83bb138524fdf

Change-Id: I04024832302a472c900f614ce03251766bc23d70
2020-02-13 17:21:14 +00:00
Monty Taylor
cc619fe589 Add review-dev01.opendev.org
Add a new review-dev server on the opendev domain with LE support
enabled.

Depends-On: https://review.opendev.org/705661
Change-Id: Ie32124cd617e9986602301f230e83bb138524fdf
2020-02-05 09:58:25 -06:00
Ian Wienand
1992a9c1ec letsencrypt: use a fake CA for self-signed testing certs
Production letsencrypt certificate generation creates an intermediate
chain file (ca.cer); to simulate this during the self-signed tests
generate a fake CA certifcate, and use that to sign the generated
server certificate.

Tests updated to look for all these files

Change-Id: I3990529bca7ff3c6413ed0066f9c4feaf5464b1c
2019-05-14 10:24:28 +10:00
Ian Wienand
dedd3a409f letsencrypt: tighten certificate permissions
Ensure the certificate material is not world-readable.  Create a
letsencrypt group, and have things owned by root but group readable.

Change-Id: I49a6a8520aca27e70b3e48d0fcc874daf1c4ff24
2019-04-11 10:32:28 +10:00
Ian Wienand
afd907c16d letsencrypt support
This change contains the roles and testing for deploying certificates
on hosts using letsencrypt with domain authentication.

From a top level, the process is implemented in the roles as follows:

1) letsencrypt-acme-sh-install

   This role installs the acme.sh tool on hosts in the letsencrypt
   group, along with a small custom driver script to help parse output
   that is used by later roles.

2) letsencrypt-request-certs

   This role runs on each host, and reads a host variable describing
   the certificates required.  It uses the acme.sh tool (via the
   driver) to request the certificates from letsencrypt.  It populates
   a global Ansible variable with the authentication TXT records
   required.

   If the certificate exists on the host and is not within the renewal
   period, it should do nothing.

3) letsencrypt-install-txt-record

   This role runs on the adns server.  It installs the TXT records
   generated in step 2 to the acme.opendev.org domain and then
   refreshes the server.  Hosts wanting certificates will have
   pre-provisioned CNAME records for _acme-challenge.host.opendev.org
   pointing to acme.opendev.org.

4) letsencrypt-create-certs

   This role runs on each host, reading the same variable as in step
   2.  However this time the acme.sh tool is run to authenticate and
   create the certificates, which should now work correctly via the
   TXT records from step 3.  After this, the host will have the
   full certificate material.

Testing is added via testinfra.  For testing purposes requests are
made to the staging letsencrypt servers and a self-signed certificate
is provisioned in step 4 (as the authentication is not available
during CI).  We test that the DNS TXT records are created locally on
the CI adns server, however.

Related-Spec: https://review.openstack.org/587283

Change-Id: I1f66da614751a29cc565b37cdc9ff34d70fdfd3f
2019-04-02 15:31:41 +11:00