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
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
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
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
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
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
Add a new review-dev server on the opendev domain with LE support
enabled.
Depends-On: https://review.opendev.org/705661
Change-Id: Ie32124cd617e9986602301f230e83bb138524fdf
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
Ensure the certificate material is not world-readable. Create a
letsencrypt group, and have things owned by root but group readable.
Change-Id: I49a6a8520aca27e70b3e48d0fcc874daf1c4ff24
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