system-config/playbooks/roles/letsencrypt-acme-sh-install/tasks/main.yaml
Jeremy Stanley 8500dcf394 Patch acme.sh/4659 for arbitrary command execution
Temporarily cherry-pick the commits which fix "acme.sh runs
arbitrary commands from a remote server"
https://github.com/acmesh-official/acme.sh/issues/4659 as trivial
backports on top of their 3.0.5 release until such time as we can
upgrade. This addresses a remote code execution vulnerability (no
CVE assigned yet) which could be exploited by the ACME protocol
operator, in our case the admins of the Let's Encrypt certificate
authority.

Change-Id: Ib052901a7aa08a9fdbd01d623f4b5d3eee938401
2023-06-11 20:41:11 +00:00

103 lines
3.1 KiB
YAML

- name: Install acme.sh client
git:
repo: https://github.com/acmesh-official/acme.sh
dest: /opt/acme.sh
# Pinned due to https://github.com/acmesh-official/acme.sh/issues/4416
version: 3.0.5
register: clone_acmesh_result
until: clone_acmesh_result is not failed
retries: 3
delay: 2
# Temporary https://github.com/acmesh-official/acme.sh/issues/4659 fix
# until we can upgrade to 3.0.6 or later
- name: Patch for issue 4659
shell: |
git -C /opt/acme.sh cherry-pick 4c30250
git -C /opt/acme.sh cherry-pick 327e2fb
- name: Install letsencrypt group
group:
name: letsencrypt
state: present
gid: "{{ letsencrypt_gid | default(omit) }}"
- name: Install driver script
copy:
src: driver.sh
dest: /opt/acme.sh/driver.sh
mode: 0755
- name: Setup log directory
file:
path: /var/log/acme.sh
state: directory
mode: 0755
- name: Setup log rotation
include_role:
name: logrotate
vars:
logrotate_file_name: /var/log/acme.sh/acme.sh.log
- name: Setup top level cert directory
file:
path: /etc/letsencrypt-certs
state: directory
owner: root
group: letsencrypt
mode: u=rwx,g=rx,o=,g+s
- name: Create acme.sh config directory
file:
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
assert:
that: letsencrypt_account_email is defined
- name: Configure account email
lineinfile:
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
stat:
path: '{{ item }}'
loop:
- /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
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)