summaryrefslogtreecommitdiff
path: root/roles/x509/acmetool/base/tasks
diff options
context:
space:
mode:
authorChristian Pointner <equinox@spreadspace.org>2022-12-22 13:01:30 +0100
committerChristian Pointner <equinox@spreadspace.org>2022-12-22 13:01:30 +0100
commit18e0446c9c545f396d7737b406e6e207748e7926 (patch)
treef3f07876c819a4fb9845c6a098adfa9553ed7819 /roles/x509/acmetool/base/tasks
parentadd prometheus snmp exporter (diff)
move acmetool to new x509 subdir
Diffstat (limited to 'roles/x509/acmetool/base/tasks')
-rw-r--r--roles/x509/acmetool/base/tasks/main.yml65
-rw-r--r--roles/x509/acmetool/base/tasks/selfsigned.yml145
2 files changed, 210 insertions, 0 deletions
diff --git a/roles/x509/acmetool/base/tasks/main.yml b/roles/x509/acmetool/base/tasks/main.yml
new file mode 100644
index 00000000..5f2ae4ab
--- /dev/null
+++ b/roles/x509/acmetool/base/tasks/main.yml
@@ -0,0 +1,65 @@
+---
+- name: check if acmetool package is new enough
+ ansible.builtin.debug:
+ msg: "Check distribution_release"
+ failed_when: (ansible_distribution == 'Debian' and (ansible_distribution_major_version | int) < 9) or (ansible_distribution == 'Ubuntu' and (ansible_distribution_major_version | int) < 17) or (ansible_distribution != 'Debian' and ansible_distribution != 'Ubuntu')
+
+- name: install needed packages
+ ansible.builtin.apt:
+ name:
+ - acmetool
+ - "{{ python_basename }}-openssl"
+ state: present
+
+- name: create initial directory structure
+ ansible.builtin.command: acmetool --batch
+ args:
+ creates: /var/lib/acme/conf
+
+- name: create acmetool response file
+ ansible.builtin.template:
+ src: responses.j2
+ dest: /var/lib/acme/conf/responses
+
+- name: create non-standard acmetool webroot path
+ ansible.builtin.file:
+ name: "{{ acmetool_challenge_webroot_path }}"
+ state: directory
+ when: acmetool_challenge_webroot_path is defined
+
+- name: run quickstart to create account and default target configuration
+ ansible.builtin.command: acmetool --batch quickstart
+ environment:
+ http_proxy: "{{ acmetool_http_proxy | default('') }}"
+ https_proxy: "{{ acmetool_https_proxy | default('') }}"
+ args:
+ creates: /var/lib/acme/conf/target
+
+- name: generate selfsigned interim certificate
+ ansible.builtin.include_tasks: selfsigned.yml
+
+- name: install service reload configuration
+ ansible.builtin.template:
+ src: acme-reload.j2
+ dest: /etc/default/acme-reload
+ owner: root
+ group: root
+ mode: 0644
+ when: acmetool_reload_services is defined
+
+- name: create system unit snippet directory
+ ansible.builtin.file:
+ path: /etc/systemd/system/acmetool.service.d/
+ state: directory
+
+- name: install systemd unit snippet
+ ansible.builtin.template:
+ src: systemd-override.conf.j2
+ dest: /etc/systemd/system/acmetool.service.d/override.conf
+
+- name: enable/start systemd timer for acmetool
+ ansible.builtin.systemd:
+ name: acmetool.timer
+ state: started
+ enabled: yes
+ daemon_reload: yes
diff --git a/roles/x509/acmetool/base/tasks/selfsigned.yml b/roles/x509/acmetool/base/tasks/selfsigned.yml
new file mode 100644
index 00000000..449fbdb9
--- /dev/null
+++ b/roles/x509/acmetool/base/tasks/selfsigned.yml
@@ -0,0 +1,145 @@
+---
+- name: get id of existing selfsigned interim certificate
+ ansible.builtin.shell: cat /var/lib/acme/.selfsigned-interim-cert || true
+ changed_when: false
+ check_mode: false
+ register: existing_selfsigned_interim_cert_id
+
+- name: set existing_selfsigned_interim_cert_id variable
+ ansible.builtin.set_fact:
+ existing_selfsigned_interim_cert_id: "{{ existing_selfsigned_interim_cert_id.stdout }}"
+
+- name: check if selfsigned interim certificate does exist
+ ansible.builtin.stat:
+ path: "/var/lib/acme/certs/{{ existing_selfsigned_interim_cert_id }}"
+ register: existing_selfsigned_interim_cert_stat
+
+- name: create selfsigned interim certificate
+ when: not existing_selfsigned_interim_cert_id or not existing_selfsigned_interim_cert_stat.stat.exists
+ block:
+ - name: create temporary directory
+ ansible.builtin.tempfile:
+ path: /var/lib/acme/tmp
+ prefix: selfsigned-interim-cert-
+ state: directory
+ register: tmpdir
+
+ - name: set tmpdir variable
+ ansible.builtin.set_fact:
+ tmpdir: "{{ tmpdir.path }}"
+
+ - name: generate private key for selfsigned interim certificate
+ ansible.builtin.openssl_privatekey:
+ path: "{{ tmpdir }}/privkey"
+ mode: 0600
+
+ - name: generate csr for selfsigned interim certificate
+ community.crypto.openssl_csr_pipe:
+ privatekey_path: "{{ tmpdir }}/privkey"
+ common_name: "{{ ansible_fqdn }}"
+ register: selfsigned_interim_cert_req
+
+
+ ### this is needed because strftime filter in ansible is exceptionally stupid
+ ### see: https://github.com/ansible/ansible/issues/39835
+ - name: get remote date-time 10s ago
+ ansible.builtin.command: date -d '10 seconds ago' -u '+%Y%m%d%H%M%SZ'
+ register: remote_datetime_10sago
+
+ - name: get remote date-time now
+ ansible.builtin.command: date -u '+%Y%m%d%H%M%SZ'
+ register: remote_datetime_now
+
+ - name: generate selfsigned interim certificate
+ community.crypto.x509_certificate_pipe:
+ privatekey_path: "{{ tmpdir }}/privkey"
+ csr_content: "{{ selfsigned_interim_cert_req.csr }}"
+ provider: selfsigned
+ ## make sure the certificate is not valid anymore to force acmetool to create a new cert
+ selfsigned_not_before: "{{ remote_datetime_10sago.stdout }}"
+ selfsigned_not_after: "{{ remote_datetime_now.stdout }}"
+ register: selfsigned_interim_cert
+
+ - name: install selfsigned interim certificate and fullchain
+ loop:
+ - cert
+ - fullchain
+ ansible.builtin.copy:
+ content: "{{ selfsigned_interim_cert.certificate }}"
+ dest: "{{ tmpdir }}/{{ item }}"
+
+ - name: create additional empty files
+ loop:
+ - chain
+ - selfsigned
+ ansible.builtin.copy:
+ content: ""
+ dest: "{{ tmpdir }}/{{ item }}"
+
+ ### TODO: remove this once acmetool respects it's own storage layout
+ ### see: https://github.com/hlandau/acme/blob/master/_doc/SCHEMA.md#temporary-use-of-self-signed-certificates
+ - name: generate fake url file
+ ansible.builtin.copy:
+ content: "https://acme.example.com/acme/cert/self-signed\n"
+ dest: "{{ tmpdir }}/url"
+
+ - name: get key id
+ ansible.builtin.shell: "openssl x509 -in '{{ tmpdir }}/cert' -noout -pubkey | openssl enc -base64 -d | openssl sha256 -binary | base32 | tr -d '=' | tr '[:upper:]' '[:lower:]'"
+ register: selfsigned_interim_key_id
+
+ - name: set selfsigned_interim_key_id variable
+ ansible.builtin.set_fact:
+ selfsigned_interim_key_id: "{{ selfsigned_interim_key_id.stdout }}"
+
+ - name: create directory for private key of selfsigned interim certificate
+ ansible.builtin.file:
+ path: "/var/lib/acme/keys/{{ selfsigned_interim_key_id }}"
+ state: directory
+ mode: 0700
+
+ - name: move private key to its directory
+ ansible.builtin.command: "mv '{{ tmpdir }}/privkey' '/var/lib/acme/keys/{{ selfsigned_interim_key_id }}/privkey'"
+
+ - name: create symlink to privkey
+ ansible.builtin.file:
+ src: "../../keys/{{ selfsigned_interim_key_id }}/privkey"
+ dest: "{{ tmpdir }}/privkey"
+ state: link
+
+ # - name: get certificate id
+ # ansible.builtin.shell: "openssl x509 -in '{{ tmpdir }}/cert' -outform der | openssl sha256 -binary | base32 | tr -d '=' | tr '[:upper:]' '[:lower:]'"
+ # register: selfsigned_interim_cert_id
+
+ # - name: set selfsigned_interim_cert_id variable
+ # ansible.builtin.set_fact:
+ # selfsigned_interim_cert_id: "selfsigned-{{ selfsigned_interim_cert_id.stdout }}"
+
+ ### TODO: replace with the above once acmetool respects it's own storage layout
+ ### see: https://github.com/hlandau/acme/blob/master/_doc/SCHEMA.md#temporary-use-of-self-signed-certificates
+ - name: get certificate id
+ ansible.builtin.shell: "cat '{{ tmpdir }}/url' | tr -d '\n' | openssl sha256 -binary | base32 | tr -d '=' | tr '[:upper:]' '[:lower:]'"
+ register: selfsigned_interim_cert_id
+
+ - name: set selfsigned_interim_cert_id variable
+ ansible.builtin.set_fact:
+ selfsigned_interim_cert_id: "{{ selfsigned_interim_cert_id.stdout }}"
+
+ - name: set permissions for selfsigned interim certificate directory
+ ansible.builtin.file:
+ path: "{{ tmpdir }}"
+ mode: 0755
+ state: directory
+
+ - name: move selfsigned interim certificate directory into place
+ ansible.builtin.command: "mv '{{ tmpdir }}' '/var/lib/acme/certs/{{ selfsigned_interim_cert_id }}'"
+
+ - name: write cert-id of selfsigned interim certificate to state directory
+ ansible.builtin.copy:
+ content: "{{ selfsigned_interim_cert_id }}"
+ dest: /var/lib/acme/.selfsigned-interim-cert
+
+ rescue:
+ - name: remove temporary directory for selfsigned interim certificate
+ ansible.builtin.file:
+ path: "{{ tmpdir }}"
+ state: absent