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
Ian Wienand 3 years ago
parent 763aa927a7
commit 3aaf87ee6d

@ -15,3 +15,9 @@ authentication procedure and parse output.
on the `/etc/letsencrypt-certificates` directory. If unset, uses
system default. Useful if this conflicts with another role that
assumes a `gid` value.
.. zuul:rolevar:: letsencrypt_account_email
:default: undefined
The email address to register with accounts. Renewal mail and
other info may be sent here. Must be defined.

@ -35,3 +35,56 @@
owner: root
group: letsencrypt
mode: u=rwx,g=rx,o=,g+s
- name: Create acme.sh config directory
path: /root/.acme.sh
state: directory
owner: root
group: root
mode: u=rwx,g=rx,o=
# An implementation note on accounts: We could share an account key
# across all our hosts and this would be the logical place to deploy
# it. However, really the only thing you can do with an account key
# is revoke a certificate if you lose the private key. It makes more
# sense to have an account per host with key material that never
# leaves the host rather than keeping a global secret that, if leaked,
# could revoke all keys simultaneously.
- name: Check for account email
that: letsencrypt_account_email is defined
- name: Configure account email
path: /root/.acme.sh/account.conf
regexp: '^ACCOUNT_EMAIL='
line: 'ACCOUNT_EMAIL={{ letsencrypt_account_email }}'
create: true
register: account_email
# If we updated the email and we have existing accounts, we should
# update the address.
# NOTE(ianw) 2020-03-04 : acme.sh dumps the 200 response json from the
# ACME api when creating an account into this file to keep track of
# the account-id. However, it doesn't actually then update it in
# response to --updateaccount although the details in the account
# *are* correctly updated. It doesn't make a difference to ongoing
# operation since all that cares about is the unchanging id, but can
# be confusing if you check this and don't see an updated email
# address. I have filed:
# https://github.com/acmesh-official/acme.sh/pull/2769
- name: Check for existing account setup
path: '{{ item }}'
- /root/.acme.sh/ca/acme-v02.api.letsencrypt.org/account.json
- /root/.acme.sh/ca/acme-staging-v02.api.letsencrypt.org/account.json
register: existing_accounts
- name: Run account update # noqa 503
shell: |
/opt/acme.sh/acme.sh --debug --updateaccount
when: account_email.changed and (existing_accounts.results | selectattr('stat.exists') | map(attribute='item') | list | length > 0)

@ -4,3 +4,5 @@
# gate, only generate a place-holder self-signed cert for testing.
letsencrypt_use_staging: True
letsencrypt_self_sign_only: True
letsencrypt_account_email: le-test@opendev.org

@ -130,3 +130,11 @@ def test_updated_handler(host):
def test_acme_sh_config(host):
if not host.backend.get_hostname().startswith('letsencrypt0'):
config = host.file('/root/.acme.sh/account.conf')
assert config.exists
assert config.contains("^ACCOUNT_EMAIL='le-test@opendev.org'")