From 7adc22f1b18b144db5e4185f5aa4e65bace0e384 Mon Sep 17 00:00:00 2001 From: Andrea Dell'Amico Date: Sun, 27 Oct 2019 20:14:15 +0100 Subject: [PATCH] Dismiss the unsupported letsencrypt-acmetool-client. Use acme-sh-client everywhere. Fix the acme.sh configuration when we do not use the dns provider. --- .../deb-ubuntu-common/meta/main.yml | 2 -- .../defaults/main.yml | 23 ++++++++++----- .../files/acme-sh-install-certs | 2 +- .../letsencrypt-acme-sh-client/tasks/main.yml | 29 ++++++++++++++++++- .../templates/acme-services-hook.j2 | 15 ++++++++++ .../templates/acme_sh_request_env.j2 | 5 ++-- 6 files changed, 62 insertions(+), 14 deletions(-) create mode 100644 library/roles/letsencrypt-acme-sh-client/templates/acme-services-hook.j2 diff --git a/library/bootstrap-roles/deb-ubuntu-common/meta/main.yml b/library/bootstrap-roles/deb-ubuntu-common/meta/main.yml index d9e546d8..67a3074d 100644 --- a/library/bootstrap-roles/deb-ubuntu-common/meta/main.yml +++ b/library/bootstrap-roles/deb-ubuntu-common/meta/main.yml @@ -4,10 +4,8 @@ dependencies: - { role: '../../library/roles/cloud-init', when: ansible_product_name == "oVirt Node" } - { role: '../../library/roles/data_disk', when: additional_disks is defined and additional_disks } - role: '../../library/roles/sshd_config' - - { role: '../library/roles/letsencrypt-acmetool-client', when: letsencrypt_acme_install is defined and letsencrypt_acme_install } - { role: '../library/roles/letsencrypt-acme-sh-client', when: letsencrypt_acme_sh_install is defined and letsencrypt_acme_sh_install } - role: '../../library/roles/iptables' - #- { role: '../../library/roles/ganglia', when: ganglia_enabled is defined } - { role: '../../library/roles/nagios', when: nagios_enabled is defined } - { role: '../../library/roles/prometheus-node-exporter', when: prometheus_enabled } diff --git a/library/roles/letsencrypt-acme-sh-client/defaults/main.yml b/library/roles/letsencrypt-acme-sh-client/defaults/main.yml index 2269dbc8..80b74568 100644 --- a/library/roles/letsencrypt-acme-sh-client/defaults/main.yml +++ b/library/roles/letsencrypt-acme-sh-client/defaults/main.yml @@ -1,5 +1,6 @@ --- -letsencrypt_acme_sh_install: False +letsencrypt_acme_install: False +letsencrypt_acme_sh_install: '{{ letsencrypt_acme_install }}' letsencrypt_acme_sh_git_install: True letsencrypt_acme_sh_git_url: https://github.com/Neilpang/acme.sh.git letsencrypt_acme_user: acme @@ -38,13 +39,17 @@ letsencrypt_acme_sh_dirs: # - '{{ letsencrypt_acme_sh_base_data_dir }}/data' letsencrypt_acme_sh_dest_dir: '{{ ansible_fqdn }}' letsencrypt_acme_sh_certs_dir: '{{ letsencrypt_acme_sh_base_data_dir }}/certs/{{ letsencrypt_acme_sh_dest_dir }}' +letsencrypt_acme_certs_dir: '{{ letsencrypt_acme_sh_certificates_install_path }}' # The various services maintainers need to put the reconfigure/restart scripts there -letsencrypt_acme_sh_services_scripts_dir: /usr/lib/acme/hooks +letsencrypt_acme_services_scripts_dir: /usr/lib/acme/hooks +letsencrypt_acme_sh_services_scripts_dir: '{{ letsencrypt_acme_services_scripts_dir }}' letsencrypt_acme_sh_explicitly_install_certs: False -letsencrypt_acme_sh_use_ecc: True -letsencrypt_acme_sh_key_lenght: ec-384 +# ECC is better, but most old distributions fail on them +letsencrypt_acme_sh_use_ecc: False +letsencrypt_acme_sh_ecc_key_lenght: ec-384 +letsencrypt_acme_sh_rsa_key_lenght: 4096 letsencrypt_acme_sh_ocsp_must_staple: False letsencrypt_acme_email: sysadmin@example.com letsencrypt_acme_sh_email: '{{ letsencrypt_acme_email }}' @@ -53,14 +58,16 @@ letsencrypt_acme_sh_standalone_port: '{{ letsencrypt_acme_standalone_port }}' letsencrypt_acme_cron_day_of_month: '*' letsencrypt_acme_cron_hour: '{{ range(1, 4) | random }}' letsencrypt_acme_cron_minute: '{{ range(0, 59) | random }}' +letsencrypt_acme_services_hook_script: /usr/local/bin/acme-services-hook # Use this when you want a single certificate. Even when multiple provider methods are needed # The dns_provider and standalone options are mutually exclusive letsencrypt_acme_sh_domains: - - '' -# - { domain: '{{ ansible_fqdn }}', dns_provider: '{{ letsencrypt_acme_sh_dns_provider_type }}', dns_alias_challenge: 'dns-challenge.example.org', standalone: True } + - { domain: '{{ ansible_fqdn }}', standalone: True } letsencrypt_acme_sh_domains_install: - - '' -# - { domain: '{{ ansible_fqdn }}', ecc: '{{ letsencrypt_acme_sh_use_ecc }}', cert_file: '{{ letsencrypt_acme_sh_certificates_install_path }}/cert', key_file: '{{ letsencrypt_acme_sh_certificates_install_path }}/privkey', fullchain_file: '{{ letsencrypt_acme_sh_certificates_install_path }}/fullchain', reloadcmd: 'letsencrypt_acme_sh_services_scripts_dir/hook_script' } + - { domain: '{{ ansible_fqdn }}', ecc: '{{ letsencrypt_acme_sh_use_ecc }}', cert_file: '{{ letsencrypt_acme_sh_certificates_install_path }}/cert', key_file: '{{ letsencrypt_acme_sh_certificates_install_path }}/privkey', fullchain_file: '{{ letsencrypt_acme_sh_certificates_install_path }}/fullchain' } +### Stuff related to the obsolete acmetool package. Needed to cleanup systems where it was installed in the past +letsencrypt_acme_ppa_repo: 'ppa:hlandau/rhea' +letsencrypt_acme_debian_repo: 'deb http://ppa.launchpad.net/hlandau/rhea/ubuntu xenial main' diff --git a/library/roles/letsencrypt-acme-sh-client/files/acme-sh-install-certs b/library/roles/letsencrypt-acme-sh-client/files/acme-sh-install-certs index b3d1d3e7..5b1925c4 100644 --- a/library/roles/letsencrypt-acme-sh-client/files/acme-sh-install-certs +++ b/library/roles/letsencrypt-acme-sh-client/files/acme-sh-install-certs @@ -12,7 +12,7 @@ else exit 1 fi -if [ -d "$ACME_SH_HOME/keys/fakeselfsignedcert" -a -d "$ACME_SH_HOME/certs/fakeselfsignedcert" ] ; then +if [ -d "$ACME_SH_HOME/keys/fakeselfsignedcert" ] && [ -d "$ACME_SH_HOME/certs/fakeselfsignedcert" ] ; then rm -fr "$ACME_SH_HOME/keys" rm -fr "$ACME_SH_HOME/certs" fi diff --git a/library/roles/letsencrypt-acme-sh-client/tasks/main.yml b/library/roles/letsencrypt-acme-sh-client/tasks/main.yml index 4e9afff3..354b7f32 100644 --- a/library/roles/letsencrypt-acme-sh-client/tasks/main.yml +++ b/library/roles/letsencrypt-acme-sh-client/tasks/main.yml @@ -1,7 +1,31 @@ --- - block: + - name: Remove the old acme package because the tool is not supported anymore. + apt: pkg=acmetool state=absent purge=yes + + - name: Remove the old letsencrypt acmetool repo on ubuntu + apt_repository: repo={{ letsencrypt_acme_ppa_repo }} state=absent update_cache=yes + + - name: Remove the old letsencrypt acmetool repo on debian + apt_repository: repo={{ letsencrypt_acme_debian_repo }} state=absent update_cache=yes + + - name: Remove the sudoers config needed to run the old acmetool package hooks + file: dest=/etc/sudoers.d/letsencrypt-acme state=absent + + - name: Remove the old acmetool script that requested certificates + file: dest=/usr/local/bin/acme-cert-request state=absent + + - name: Remove the old letsencrypt cron job + cron: name="Letsencrypt certificate renewal" user={{ letsencrypt_acme_user }} state=absent + + tags: [ 'letsencrypt', 'letsencrypt_acme_sh' ] + +- block: + - name: Install the socat utility, needed when using the http protocols to request the certificates + apt: pkg=socat cache_valid_time=1800 + - name: Install the git client if we are installing using git - apt: pkg=git update_cache=yes cache_valid_time=1800 + apt: pkg=git cache_valid_time=1800 when: letsencrypt_acme_sh_git_install - name: Create the letsencrypt acme user @@ -27,6 +51,9 @@ - name: Install a script that installs the issued certificates copy: src=acme-sh-install-certs dest=/usr/local/bin/acme-sh-install-certs owner=root group=acme mode=0750 + - name: Install the script that will run the services hooks when a certificate is installed + template: src=acme-services-hook.j2 dest=/usr/local/bin/acme-services-hook owner=root group=acme mode=0750 + - name: Install the scripts that will be run as a cron job copy: src={{ item }} dest=/usr/local/bin/{{ item }} owner=root group=acme mode=0750 with_items: diff --git a/library/roles/letsencrypt-acme-sh-client/templates/acme-services-hook.j2 b/library/roles/letsencrypt-acme-sh-client/templates/acme-services-hook.j2 new file mode 100644 index 00000000..d3e24359 --- /dev/null +++ b/library/roles/letsencrypt-acme-sh-client/templates/acme-services-hook.j2 @@ -0,0 +1,15 @@ +#!/bin/bash + +ACME_LETSENCRYPT_HOOKS_DIR=/usr/lib/acme/hooks + +if [ -f "/etc/default/acme_sh_request_env" ] ; then + source "/etc/default/acme_sh_request_env" +else + exit 1 +fi + +for script in "${ACME_LETSENCRYPT_HOOKS_DIR}"/* ; do + if [ -x "$script" ] ; then + $script + fi +done diff --git a/library/roles/letsencrypt-acme-sh-client/templates/acme_sh_request_env.j2 b/library/roles/letsencrypt-acme-sh-client/templates/acme_sh_request_env.j2 index 15ae2615..0869eb71 100644 --- a/library/roles/letsencrypt-acme-sh-client/templates/acme_sh_request_env.j2 +++ b/library/roles/letsencrypt-acme-sh-client/templates/acme_sh_request_env.j2 @@ -10,6 +10,7 @@ ACME_SH_ISSUE_LOG_FILE={{ letsencrypt_acme_sh_base_data_dir }}/logs/cert_issue.l ACME_SH_CRON_LOG_FILE={{ letsencrypt_acme_sh_base_data_dir }}/logs/cron.log ACME_SH_INSTALL_LOG_FILE={{ letsencrypt_acme_sh_log_dir }}/cert_install.log ACME_SH_GIT_DIST_DIR={{ letsencrypt_acme_git_dest_dir }} +ACME_LETSENCRYPT_HOOKS_DIR={{ letsencrypt_acme_services_scripts_dir }} ACME_SH_INSTALL_CERTS={{ letsencrypt_acme_sh_explicitly_install_certs }} @@ -25,7 +26,7 @@ ACME_SH_INSTALL_OPTS="$ACME_SH_INSTALL_OPTS --home {{ letsencrypt_acme_sh_user_h # # Certificate issue options # -ACME_SH_ISSUE_CERT_REQUEST="--issue -k {{ letsencrypt_acme_sh_key_lenght }} --log {{ letsencrypt_acme_sh_base_data_dir }}/logs/acme.sh.log" +ACME_SH_ISSUE_CERT_REQUEST="--issue -k {% if letsencrypt_acme_sh_use_ecc %}{{ letsencrypt_acme_sh_ecc_key_lenght }}{% else %}{{ letsencrypt_acme_sh_rsa_key_lenght }}{% endif %} --log {{ letsencrypt_acme_sh_base_data_dir }}/logs/acme.sh.log" {% if letsencrypt_acme_sh_ocsp_must_staple %} ACME_SH_ISSUE_CERT_REQUEST="$ACME_SH_ISSUE_CERT_REQUEST --ocsp" {% endif %} @@ -51,7 +52,7 @@ ACME_SH_INSTALL_CERT_REQUEST="$ACME_SH_INSTALL_CERT_REQUEST --ecc" {% if letsencrypt_acme_sh_use_syslog %} ACME_SH_INSTALL_CERT_DOMAINS="$ACME_SH_INSTALL_CERT_DOMAINS --syslog {{ letsencrypt_acme_sh_syslog_level }}" {% endif %} -ACME_SH_INSTALL_CERT_DOMAINS="{% for dom in letsencrypt_acme_sh_domains_install %} -d {{ dom.domain }} --cert-file {{ dom.cert_file }} --key-file {{ dom.key_file }} --fullchain-file {{ dom.fullchain_file }} --reloadcmd {{ dom.reloadcmd }} {% endfor %}" +ACME_SH_INSTALL_CERT_DOMAINS="{% for dom in letsencrypt_acme_sh_domains_install %} -d {{ dom.domain }} --cert-file {{ dom.cert_file }} --key-file {{ dom.key_file }} --fullchain-file {{ dom.fullchain_file }} --reloadcmd {{ dom.reloadcmd | default('/usr/local/bin/acme-services-hook') }} {% endfor %}" # The complete command line to install a certificate. Run as root ACME_SH_INSTALL_CERT_REQUEST="$ACME_SH_INSTALL_CERT_REQUEST $ACME_SH_INSTALL_CERT_DOMAINS"